Skip to Content
API ReferenceDefinitions

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, definition objects MUST be created via a factory. Direct, one-off calls to createNexusDefinition<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 via interceptors.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. Set server.cache: 'force-cache' explicitly only when you want static caching or ISR.
  • Naming: Use the *Definition suffix for clarity (e.g., productDefinition, listWithTotalDefinition).

Typing

  • Prefer transport-oriented types: Product, ProductListResponse.
  • The generic response type flows into nexus, useNexusQuery, useNexusMutation, and nexusCache.
  • For runtime schemas (e.g., Zod), derive TypeScript types from the schema and keep names consistent (ProductSchematype Product = z.infer<...>).

Patterns and Anti-patterns

Patterns

  • Create dynamic definition objects 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 tags consistently to enable precise server and client revalidation.

Anti-patterns

  • Mixing server-only APIs inside delegated subtrees.
  • Omitting tags and 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 route prop, the runtime clears baseURL and uses the route path as the endpoint.

See also

Last updated on