Definitions
createNexusDefinition lets you define requests in a single, predictable format that both the server and client can use.
Import
import { createNexusDefinition } from "next-nexus";Important: In this project,
definitionobjects MUST be created via a factory. Direct, one-off calls tocreateNexusDefinition<T>({...})are not allowed.
Factory Usage (Required)
Create a factory with shared defaults, then derive domain-specific definition objects from it.
export const createApiDefinition = createNexusDefinition({
baseURL: "https://api.example.com",
timeout: 5,
retry: { count: 1, delay: 1 },
headers: { "x-app": "docs" },
});
export const productDefinition = {
list: createApiDefinition<Product[]>({
method: "GET",
endpoint: "/products",
server: {
// next-nexus defaults server.cache to 'no-store'; set 'force-cache' only if you want static caching/ISR
revalidate: 1800, // maps to next: { revalidate: 1800 }
tags: ["products"], // maps to next: { tags: ['products'] }
},
client: { tags: ["products"], revalidate: 300 },
}),
detail: (id: string) =>
createApiDefinition<Product>({
method: "GET",
endpoint: `/products/${id}`,
client: { tags: ["products", `product:${id}`], revalidate: 300 },
}),
like: (id: string) =>
createApiDefinition<{ success: boolean }>({
method: "POST",
endpoint: `/products/${id}/like`,
}),
};Cached Response Headers
Use client.cachedHeaders to cache safe, small headers (e.g., x-total-count) alongside the hydrated data.
Define
export const listWithTotalDefinition = createApiDefinition<Product[]>({
method: 'GET', endpoint: '/products',
client: { tags: ['products'], revalidate: 300, cachedHeaders: ['x-total-count'] }
})Notes
- Do not cache sensitive headers.
- Headers are restored from the hydration payload without extra requests.
Options
method: ‘GET’ | ‘POST’ | ‘PUT’ | ‘PATCH’ | ‘DELETE’endpoint: string (path part)baseURL?: string (prepends endpoint)headers?: HeadersInit (merged; falsy string values like'null'or'undefined'remove the header)server?:{ cache?: RequestCache; revalidate?: number; tags?: string[] }client?:{ revalidate?: number; tags?: string[]; cachedHeaders?: string[] }timeout?: number (seconds)retry?:{ count: number; delay?: number }interceptors?: string[] (names registered viainterceptors.request/response.use)
Defaults
server.cache: If omitted, next-nexus defaults to'no-store'regardless of the Next.js version. Next.js 14 defaults to'force-cache', while Next.js 15+ defaults to'no-store'. next-nexus keeps'no-store'as the default for consistency. Setserver.cache: 'force-cache'explicitly only when you want static caching or ISR.- Naming: Use the
*Definitionsuffix for clarity (e.g.,productDefinition,listWithTotalDefinition).
Typing
- Prefer transport-oriented types:
Product,ProductListResponse. - The generic response type flows into
nexus,useNexusQuery,useNexusMutation, andnexusCache. - For runtime schemas (e.g., Zod), derive TypeScript types from the schema and keep names consistent (
ProductSchema→type Product = z.infer<...>).
Patterns and Anti-patterns
Patterns
- Create dynamic
definitionobjects for parameterized endpoints by using the factory:const detail = (id: string) => createApiDefinition<Product>({ method: "GET", endpoint: `/products/${id}` }); - Cache small, safe response headers via
client.cachedHeaders(e.g.,x-total-count). - Use
tagsconsistently to enable precise server and client revalidation.
Anti-patterns
- Mixing server-only APIs inside delegated subtrees.
- Omitting
tagsand then trying to revalidate precise slices of data later. - Defining requests without the shared factory, which can lead to inconsistency and type-safety issues.
Tips
- Header merging: Using the string values
'null'or'undefined'for a header will remove it after merging. - Route proxying: When hooks are passed a
routeprop, the runtime clearsbaseURLand uses the route path as the endpoint.
See also