Create API Routes & Fetch with SWR
Letβs make a simple API route and fetch data from it using SWR.
π Step 1: Create an API route
Create a new file under app/api/hello/route.ts
.
// app/api/hello/route.ts
export async function GET() {
return Response.json({ message: "Hello from the API!" });
}
π§ Step 2: Fetch data with SWR
Now letβs use it in a component:
"use client";
import config from "@/config";
import { fetcher } from "@/lib/utils";
import useSWR from "swr";
function HelloMessage() {
const { data, isLoading, error } = useSWR(
`${config.api.url}/hello`,
fetcher,
{
refreshInterval: 500, // optional polling
}
);
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error loading chat</div>;
return (
<div className="text-3xl font-[600] mt-36 mx-auto w-fit">
{data?.message}
</div>
);
}
export default HelloMessage;
Make sure to update NEXT_PUBLIC_PRODUCTION_URL
when you deploy your app
and API. Your mobile app fetches data from this endpoint, so the API must be
deployed first.
π Step 3: Send POST Requests with Auth + Refresh UI
Letβs build a secure POST request and instantly update the UI with mutate()
from SWR.
π§± Create a POST API route
// app/api/chat/route.ts
export async function POST(req: Request) {
const body = await req.json();
// π Get auth token from header
const token = req.headers.get("Authorization")?.replace("Bearer ", "");
console.log("Received token:", token);
return Response.json({
message: `You said: ${body.text}`,
});
}
π Add Authorization Header (Bearer token)
const res = await fetch(`${config.api.url}/chat`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${user.token}`, // π Add your token here
},
body: JSON.stringify({ text }),
});
Make sure user.token is securely retrieved (e.g. from your auth provider).
π Use mutate to refresh cached data
import useSWR, { mutate } from "swr";
const sendMessage = async () => {
await fetch(`${config.api.url}/chat`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text }),
});
mutate(`/api/chat`); // π Re-fetch latest data from API
};
Want to go deeper? Learn more on the SWR official website β (opens in a new tab)
π Step 4: Support CORS with OPTIONS Handler
When sending requests from a mobile app, especially with custom headers, the browser or WebView may first send an OPTIONS preflight request. If your API route doesnβt respond to it, the request will fail.
To support this, add an OPTIONS handler to your route:
// app/api/chat/route.ts
export async function OPTIONS() {
return new Response(null, {
status: 204,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,POST,OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
},
});
}
This ensures your endpoint handles preflight checks properly, allowing mobile apps (and other clients) to make authenticated POST requests with no issues.