• Blog
  • Documentation
  • Courses
  • Changelog
  • AI Starters
  • UI Kit
  • FAQ
  • Supamode
    New
  • Pricing

Launch your next SaaS in record time with Makerkit, a React SaaS Boilerplate for Next.js and Supabase.

Makerkit is a product of Makerkit Pte Ltd (registered in the Republic of Singapore)Company Registration No: 202407149CFor support or inquiries, please contact us

About
  • FAQ
  • Contact
  • Verify your Discord
  • Consultation
  • Open Source
  • Become an Affiliate
Product
  • Documentation
  • Blog
  • Changelog
  • UI Blocks
  • Figma UI Kit
  • AI SaaS Starters
License
  • Activate License
  • Upgrade License
  • Invite Member
Legal
  • Terms of License
    • Adding API Routes
    • Change Authentication strategy
    • Fetching the signed in User
    • Reading a Document
    • Creating a Document
    • Configuring Plans
    • Project Configuration
    • Updating the Navigation menu
    • Adding a new translation string
    • Guarding an API Route
    • Adding Pages
    • Updating the Sidebar menu
    • Require Email Verification
    • Fetching the selected Organization
    • Reading a list of Documents
    • Updating a Document
    • Running the Stripe Webhook locally
    • Branding
    • Setting a Default Language
    • Dark Theme
    • Theming
    • Calling API Routes from the client
    • Deleting a Document
    • Updating the Logo
    • Adding a new language in the Next.js Firebase SaaS Kit
    • Checking CSRF Tokens
    • Passing data from server to client
    • Updating the Fonts
    • Adding Pages
    • Guarding Pages
    • Using Lemon Squeezy instead of Stripe
    • Updating the Favicons
    • Using the Language Switcher
    • Environment variables
    • Detect current Locale
    • Setting up Emails

Calling API Routes from the client-side using SWR | Next.js Firebase SaaS Kit

Learn how to use SWR to call your Next.js Firebase API route handlers from React components

Makerkit includes the library SWR, a data-fetching React utility written by Vercel, the creators of Next.js.

This library is useful for making asynchronous requests from your React components - primarily to API Routes.

Why is it useful? SWR makes it simpler to fetch and mutate data, caching and revalidating. Let's see how we can use it to make requests to our endpoints.

Using SWR for fetching data from an API Route Handler

Let's assume we have a very simple API Route at /api/data:

app/api/data.ts
import { NextApiRequest, NextApiResponse } from "next";
export default async function apiHandler(
req: NextApiRequest,
res: NextApiResponse
) {
return res.json({
hello: "world"
});
}

As you may know, we can call the endpoint /api/data using a GET request and will receive the JSON response { "hello": "world" }.

Now, we want to call this from our Next.js application using SWR, and use it within a React component.

We proceed building a React Hook with SWR which is able to fetch the data from our endpoint /api/data:

tsx
import useSWR from 'swr';
export function useFetchData() {
const key = '/api/data';
return useSWR<{ hello: string }>([key], async () => {
return fetch(key).then(res => res.json());
});
}

Now, we can call this endpoint from any React component:

tsx
function MyComponent() {
const { data, isLoading, error } = useFetchData();
if (isLoading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Error...</p>;
}
return <div>{data.hello}</div>
}

Mutating data with SWR

When it comes to mutating data, we can use the swr/mutation utility, designed to make mutations simple.

As you may know, mutations will likely use the method POST, PUT, PATCH, or DELETE. In these cases, the middleware in the kit will require us to send a CSRF token for security reasons.

As such, we provide a handy wrapper around fetch.

Let's write a very simple API Route that makes a mutation: we add a new record in the tasks collection, and return the ID back to the client.

tsx
import { NextApiRequest, NextApiResponse } from "next";
import getRestFirestore from '~/core/firebase/admin/get-rest-firestore';
import { withPipe } from '~/core/middleware/with-pipe';
import { withCsrf } from '~/core/middleware/with-csrf';
import { withAuthedUser } from '~/core/middleware/with-authed-user';
async function apiHandler(
req: NextApiRequest,
res: NextApiResponse
) {
const firestore = getRestFirestore();
const collection = firestore.collection('tasks');
const data = await collection.add({
name: req.body.name
});
return res.json({ id: data.id });
}
export default withPipe(
withAuthedUser,
withCsrf(),
apiHandler,
);

Now, let's write a React Hook that calls this endpoint using SWR.

tsx
import useMutation from 'swr/mutation';
import { useApiRequest } from '~/core/hooks/use-api';
interface Task {
name: string;
}
function useInsertTask() {
const fetcher = useApiRequest();
const path = '/api/task';
return useMutation(
path, async (_, data: { arg: Task }) => {
return fetcher({
path,
body: data.arg,
method: 'POST'
});
}
);
}

What does useApiRequest do? This hook automatically inserts the CSRF token in our fetch requests, so that you don't have to.

If you prefer not using it, you can manually add the CSRF token instead:

tsx
import useMutation from 'swr/mutation';
import { useCsrfToken } from "~/core/firebase/hooks/use-csrf-token";
interface Task {
name: string;
}
function useInsertTask() {
const csrfToken = useCsrfToken();
const path = '/api/task';
return useMutation(
path, async (_, data: { arg: Task }) => {
return fetch(path, {
body: JSON.stringify(data.arg),
method: 'POST',
headers: {
'x-csrf-token': csrfToken
}
});
}
);
}

We can now call the mutation from a React component:

tsx
function TaskForm() {
const insertTaskMutation = useInsertTask();
const onSubmit: React.FormEventHandler<HTMLFormElement> = (event) => {
const name = new FormData(event.currentTarget).get('name') ?? 'No Name';
const task = { name };
return insertTaskMutation.trigger(task);
};
return (
<form onSubmit={onSubmit}>
<input type={'name'} required />
<button disabled={insertTaskMutation.isLoading}>
Submit
</button>
</form>
);
}
On this page
  1. Using SWR for fetching data from an API Route Handler
    1. Mutating data with SWR