Standard patterns for HTTP/API clients in Next.js 16+ App Router frontends: where to put the client, how to type it, how to handle errors, and how to attach auth headers in a reusable way.
Use this Skill whenever you are:
This Skill must work for any Next.js App Router project that calls a backend over HTTP, not just a single repo.
fetch calls across the app.Place the main client in a dedicated module, for example:
src/lib/api.ts orapp/(lib)/api.tsAdjust the exact path to match the project, but keep a single, obvious API entrypoint.
Export functions from this module with clear names, such as:
getTasks(), createTask(payload), updateTask(id, payload),
deleteTask(id), etc.getUserProfile(), updateUserProfile(payload), etc.Do not call fetch or low-level HTTP functions directly from pages
or components unless there is a very strong reason. Prefer calling
the functions exposed by the API client module.
Default to the built-in fetch API in Next.js:
fetch in server components for server-side data fetching.fetch or a small wrapper in client components when
client-side fetching is required (e.g. in hooks).If a third-party client (axios, ky, etc.) is used, it must be configured in a single place and then imported from there. Do not configure clients in multiple files.
For each API function, define TypeScript types or interfaces that describe:
Prefer importing shared types from a central types module if the
project has one; otherwise, define local types next to the API
client code.
Do not use any for API responses. If the schema is not yet stable,
start with minimal but meaningful types (e.g. Task, User, ApiError).
Wrap API calls in helper functions that translate low-level HTTP errors into a consistent error shape for the UI.
Define a simple error model, for example:
{ message: string; status?: number; details?: unknown }On non-2xx HTTP status codes:
Do not scatter try/catch with custom logic in every component.
Centralize error interpretation inside the API client.
Do not manually attach auth headers (e.g. Authorization: Bearer ...)
in every component.
Provide a single place in the API client where headers are built:
headers object.Keep the pattern generic:
For Server Components:
fetch calls with server-side environment variables
and base URLs.For Client Components:
useTasks) that call
the central API client and manage loading/error state.Do not mix server-only and client-only logic in the same file. Keep server and client concerns clearly separated.
Store the API base URL and other configuration in a single place:
e.g. lib/config.ts with:
API_BASE_URLNever hard-code full URLs all over the codebase.
Central configuration makes it easy to switch between local, staging, and production backends.
When using Next.js data fetching in server components, respect the project’s chosen caching strategy:
cache: "no-store" for always-fresh data.next: { revalidate: N } for periodic revalidation.Keep these options close to the API client so behaviour is consistent for all callers.
fetch calls into many components with slightly
different error handling and headers.Response objects from the API client; prefer returning
typed data or throwing a clear error.Whenever possible, this Skill should align with the project’s existing conventions, for example:
@/lib/api.ts or similar central API client module.@/lib/config.ts or .env-backed configuration helpers.@/types or @/lib/types.If these files are missing, propose creating them using the patterns described above instead of inventing a completely new API access style.