nextjs-frontend-api-client-patterns
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.
$ 安裝
git clone https://github.com/majiayu000/claude-skill-registry /tmp/claude-skill-registry && cp -r /tmp/claude-skill-registry/skills/design/nextjs-frontend-api-client-patterns ~/.claude/skills/claude-skill-registry// tip: Run this command in your terminal to install the skill
name: nextjs-frontend-api-client-patterns description: > 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.
Next.js Frontend API Client Patterns Skill
When to use this Skill
Use this Skill whenever you are:
- Creating or modifying the code that calls a backend API from a Next.js 16+ App Router frontend.
- Designing how the frontend talks to any HTTP/REST/JSON API (FastAPI, Node, Go, etc.).
- Adding new API functions (getTasks, createTodo, updateProfile, etc.).
- Improving error handling, typing, or auth token handling for API calls.
This Skill must work for any Next.js App Router project that calls a backend over HTTP, not just a single repo.
Core goals
- All API calls go through one central client module instead of being
scattered
fetchcalls across the app. - API requests and responses are strongly typed with TypeScript.
- Error handling is consistent and predictable for UI components.
- Auth headers (e.g. JWT Bearer tokens) are attached in one place, not manually per call.
- The pattern is reusable across many projects with minimal changes.
File and module conventions
-
Place the main client in a dedicated module, for example:
src/lib/api.tsorapp/(lib)/api.ts
Adjust 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
fetchor 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.
HTTP client choices
-
Default to the built-in
fetchAPI in Next.js:- Use
fetchin server components for server-side data fetching. - Use
fetchor a small wrapper in client components when client-side fetching is required (e.g. in hooks).
- Use
-
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.
Typing requests and responses
-
For each API function, define TypeScript types or interfaces that describe:
- The request payload (if any).
- The expected response shape.
-
Prefer importing shared types from a central
typesmodule if the project has one; otherwise, define local types next to the API client code. -
Do not use
anyfor API responses. If the schema is not yet stable, start with minimal but meaningful types (e.g.Task,User,ApiError).
Error handling patterns
-
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:
- Parse the response body (if JSON) and map it to the error model.
- Throw or return a predictable error object that components can use to show messages.
-
Do not scatter
try/catchwith custom logic in every component. Centralize error interpretation inside the API client.
Auth and headers
-
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:
- For example, a helper that receives a token or session and returns
the appropriate
headersobject. - Or a wrapper function that reads the token from a trusted source (e.g. cookies, session object) and attaches it.
- For example, a helper that receives a token or session and returns
the appropriate
-
Keep the pattern generic:
- The Skill should not assume a specific auth provider name.
- It may refer to “JWT Bearer token in the Authorization header” as a common pattern.
Server vs client usage
-
For Server Components:
- Prefer direct
fetchcalls with server-side environment variables and base URLs. - Use the same API client module, but ensure any client-only code (window, localStorage) is not used.
- Prefer direct
-
For Client Components:
- Expose simple, typed functions or hooks (e.g.
useTasks) that call the central API client and manage loading/error state.
- Expose simple, typed functions or hooks (e.g.
-
Do not mix server-only and client-only logic in the same file. Keep server and client concerns clearly separated.
Base URL and configuration
-
Store the API base URL and other configuration in a single place:
-
e.g.
lib/config.tswith:API_BASE_URL- any feature flags or environment-dependent settings.
-
-
Never hard-code full URLs all over the codebase.
-
Central configuration makes it easy to switch between local, staging, and production backends.
Caching and revalidation (optional)
-
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.
Things to avoid
- Copy-pasting raw
fetchcalls into many components with slightly different error handling and headers. - Returning raw
Responseobjects from the API client; prefer returning typed data or throwing a clear error. - Mixing multiple different HTTP client libraries in the same project.
- Hard-coding tokens, secrets, or environment-specific URLs in components or pages.
References inside the repo
Whenever possible, this Skill should align with the project’s existing conventions, for example:
@/lib/api.tsor similar central API client module.@/lib/config.tsor.env-backed configuration helpers.- Shared types under
@/typesor@/lib/types.
If these files are missing, propose creating them using the patterns described above instead of inventing a completely new API access style.
Repository
