new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Next.js · API reference · all subjects

functions

556 notes in this subject, read out of this brain and free to use. This is page 9 of 10.

generateStaticParams empty array for all paths at runtime

To statically render all paths the first time they're visited at runtime (not at build time), return an empty array from generateStaticParams.

generateStaticParams must return an array

You must always return an array from generateStaticParams, even if it is empty. Otherwise, the route will be dynamically rendered.

export const dynamic = 'force-static' with generateStaticParams

You can utilize export const dynamic = 'force-static' in order to revalidate (ISR) paths at runtime, as an alternative to returning an empty array from generateStaticParams.

generateStaticParams with Cache Components empty array requirement

When using Cache Components with dynamic routes, generateStaticParams must return at least one param. Empty arrays cause a build error. This allows Cache Components to validate that your route does not incorrectly access cookies(), headers(), or searchParams at runtime.

generateStaticParams segment generation scope

You can generate params for dynamic segments above the current layout or page, but not below. For example, in app/products/[category]/[product]/page.js, you can generate params for both [category] and [product], but in app/products/[category]/layout.js, you can only generate params for [category].

generateStaticParams top-down approach execution

A child route segment's generateStaticParams function is executed once for each segment a parent generateStaticParams generates. The child generateStaticParams function can use the params returned from the parent generateStaticParams function to dynamically generate its own segments.

generateStaticParams parent params synchronous access

When a child generateStaticParams receives params from the parent, the params argument can be accessed synchronously and includes only parent segment params.

fetch request memoization in generateStaticParams

Fetch requests are automatically memoized for the same data across all generate-prefixed functions, Layouts, Pages, and Server Components. React cache can be used if fetch is unavailable.

generateStaticParams with Route Handlers example

generateStaticParams can be used with Route Handlers to statically generate API responses at build time. Example: export async function generateStaticParams() { return [{ id: '1' }, { id: '2' }, { id: '3' }] } export async function GET(request, { params }) { const { id } = await params; return Response.json({ id, title: `Post ${id}` }) }

generateStaticParams multiple dynamic segments example

Example of generateStaticParams with multiple dynamic segments: export function generateStaticParams() { return [{ category: 'a', product: '1' }, { category: 'b', product: '2' }, { category: 'c', product: '3' }] } generates three versions of the page: /products/a/1, /products/b/2, /products/c/3.

generateStaticParams catch-all segment example

Example of generateStaticParams with a catch-all segment: export function generateStaticParams() { return [{ slug: ['a', '1'] }, { slug: ['b', '2'] }, { slug: ['c', '3'] }] } generates three versions of the page: /product/a/1, /product/b/2, /product/c/3.

generateStaticParams subset prerendering example

To statically render a subset of paths at build time: export async function generateStaticParams() { const posts = await fetch('https://.../posts').then((res) => res.json()); return posts.slice(0, 10).map((post) => ({ slug: post.slug })) } This renders the first 10 posts at build time.

generateStaticParams with dynamicParams false example

Example combining generateStaticParams with dynamicParams = false: export const dynamicParams = false; export async function generateStaticParams() { const posts = await fetch('https://.../posts').then((res) => res.json()); const topPosts = posts.slice(0, 10); return topPosts.map((post) => ({ slug: post.slug })) } This means all posts besides the top 10 will be a 404.

generateStaticParams all paths at runtime example

Example to statically render all paths the first time they're visited: export async function generateStaticParams() { return [] } This returns an empty array so no paths will be rendered at build time.

generateStaticParams top-down approach with parent params example

Example of generating params from the top down using parent params: export async function generateStaticParams({ params: { category } }) { const products = await fetch(`https://.../products?category=${category}`).then((res) => res.json()); return products.map((product) => ({ product: product.id })) }. This child generateStaticParams function uses the category param from the parent.

generateStaticParams with use cache in Route Handler example

Example combining generateStaticParams with use cache in a Route Handler: export async function generateStaticParams() { return [{ id: '1' }, { id: '2' }, { id: '3' }] } async function getPost(id: Promise<string>) { 'use cache'; const resolvedId = await id; const response = await fetch(`https://api.example.com/posts/${resolvedId}`); return response.json() } export async function GET(request, { params }) { const post = await getPost(params.then((p) => p.id)); return Response.json(post) }

generateStaticParams version history

generateStaticParams was introduced in v13.0.0.

taint API security warning

Do not rely on the taint API as your only mechanism to prevent exposing sensitive data to the client. The taint API should be used as a defensive measure but should not be the sole protection strategy for sensitive data.

experimental_taintObjectReference usage

The experimental_taintObjectReference function from React taints object references to prevent them from crossing the Server-Client boundary. It takes two parameters: a message string and the object to taint. When a tainted object is passed through the Server-Client boundary, React throws an error. Individual fields can still be extracted and passed to Client Components separately.

experimental_taintObjectReference example

import { experimental_taintObjectReference } from 'react' function getUserDetails(id: string): UserDetails { const user = await db.queryUserById(id) experimental_taintObjectReference( 'Do not use the entire user info object. Instead, select only the fields you need.', user ) return user } Then in a Server Component, extract individual fields: const userDetails = await getUserDetails(id); return <UserCard firstName={userDetails.firstName} lastName={userDetails.lastName} />. Passing the entire object throws an error: return <UserCard user={userDetails} /> throws an error.

experimental_taintUniqueValue usage

The experimental_taintUniqueValue function from React taints specific unique values within an object to prevent them from crossing the Server-Client boundary. It takes three parameters: a message string, the parent object, and the specific property to taint. When a tainted unique value is reassigned to a variable, that variable remains tainted. However, values derived from tainted unique values (such as string interpolation) are exposed to the client.

experimental_taintUniqueValue example

import { experimental_taintUniqueValue } from 'react' function getSystemConfig(): SystemConfig { const config = await config.getConfigDetails() experimental_taintUniqueValue( 'Do not pass configuration tokens to the client', config, config.SERVICE_API_KEY ) return config } Other properties can be accessed: const systemConfig = await getSystemConfig(); return <ClientDashboard version={systemConfig.SERVICE_API_VERSION} />. Passing the tainted value throws an error: const version = systemConfig.SERVICE_API_KEY; return <ClientDashboard version={version} /> throws an error. Derived values are not protected: const version = `version::${systemConfig.SERVICE_API_KEY}` does not throw an error.

taint API limitations

Tainting can only keep track of objects by reference. Copying an object creates an untainted version, which loses all guarantees given by the API and the copy must be tainted separately. Tainting cannot keep track of data derived from a tainted value—the derived value must also be tainted. Values are tainted only for as long as their lifetime reference is within scope.

taint API use cases

The taint APIs are helpful when: the methods to read data are out of your control, you have to work with sensitive data shapes not defined by you, or sensitive data is accessed during Server Component rendering. It is recommended to model your data and APIs so that sensitive data is not returned to contexts where it is not needed.

useOffline hook availability

When useOffline is enabled, the useOffline hook is made available from the next/offline import path, allowing Client Components to read the current offline state.

NextAdapter interface definition

The NextAdapter interface is imported from the 'next' package. It requires a name property (string). It optionally includes modifyConfig (function that receives config and ctx with phase, nextVersion, projectDir; returns Promise<NextConfigComplete> or NextConfigComplete) and onBuildComplete (function that receives ctx with routing, outputs, projectDir, repoRoot, distDir, config, nextVersion, buildId; returns Promise<void> or void).

NextAdapter modifyConfig method

The modifyConfig method is optional on NextAdapter. It receives the Next.js config object and a context object containing phase (PHASE_TYPE), nextVersion (string), and projectDir (string). It can return either a Promise<NextConfigComplete> or NextConfigComplete. It is used to modify the Next.js config based on the build phase.

NextAdapter onBuildComplete method

The onBuildComplete method is optional on NextAdapter. It receives a context object with the following properties: routing (object with beforeMiddleware, beforeFiles, afterFiles, dynamicRoutes, onMatch, fallback arrays of Route objects, shouldNormalizeNextData boolean, and rsc RoutesManifest object), outputs (AdapterOutputs object), projectDir (string), repoRoot (string), distDir (string), config (NextConfigComplete), nextVersion (string), and buildId (string). It returns Promise<void> or void. This method is called after the build completes.

AdapterOutputs interface

The AdapterOutputs interface contains: pages (array of AdapterOutput['PAGES']), middleware (optional AdapterOutput['MIDDLEWARE']), appPages (array of AdapterOutput['APP_PAGE']), pagesApi (array of AdapterOutput['PAGES_API']), appRoutes (array of AdapterOutput['APP_ROUTE']), prerenders (array of AdapterOutput['PRERENDER']), staticFiles (array of AdapterOutput['STATIC_FILE']).

Route type definition for adapters

The Route type has the following properties: source (optional string), sourceRegex (string, required), destination (optional string), headers (optional Record<string, string>), has (optional RouteHas array), missing (optional RouteHas array), status (optional number), priority (optional boolean).

Creating a basic adapter module

An adapter is a module that exports an object implementing the NextAdapter interface. The adapter object must have a name property. Import NextAdapter from the 'next' package for type checking. The adapter is exported as a CommonJS module using module.exports.

Basic adapter example with modifyConfig and onBuildComplete

The following is a minimal working adapter example: ```js const adapter = { name: 'my-custom-adapter', async modifyConfig(config, { phase }) { if (phase === 'phase-production-build') { return { ...config, } } return config }, async onBuildComplete({ routing, outputs, projectDir, repoRoot, distDir, config, nextVersion, buildId, }) { console.log('Build completed with', outputs.pages.length, 'pages') console.log('Build ID:', buildId) console.log('Dynamic routes:', routing.dynamicRoutes.length) for (const page of outputs.pages) { console.log('Page:', page.pathname, 'at', page.filePath) } for (const apiRoute of outputs.pagesApi) { console.log('API Route:', apiRoute.pathname, 'at', apiRoute.filePath) } for (const appPage of outputs.appPages) { console.log('App Page:', appPage.pathname, 'at', appPage.filePath) } for (const prerender of outputs.prerenders) { console.log('Prerendered:', prerender.pathname) } }, } module.exports = adapter ``` This example shows how to create an adapter that modifies config during production builds and logs build output information after compilation completes.

io() function purpose

The io() function informs Next.js that an IO operation follows. When Cache Components is enabled, it helps decide whether to capture a synchronous value like new Date() or Math.random() once for the static shell and reuse it for every visitor, or produce it fresh for each request. To capture the value in the static shell, wrap it in 'use cache'. To keep it out of the static shell, use await io(), which suspends during prerendering.

io() behavior during prerendering

When Cache Components is enabled and await io() is called in a Server Component during prerendering, it suspends and execution stops, excluding the code that follows from the prerender output. The code can be wrapped in a Suspense boundary with a fallback that ships in the static shell.

io() behavior in cached scopes, during requests, in browser, and without Cache Components

During a request, inside cached scopes, in the browser, and in apps without Cache Components (including the Pages Router), calling io() resolves immediately.

io() with Server Components example

In a Server Component, call await io() before reading a synchronous value. The CurrentTime component wrapped in a Suspense boundary will have its fallback shipped in the static shell during prerender when await io() suspends. If CurrentTime were inside a 'use cache' scope instead, io() would be a no-op, the value would be captured into the static shell and no Suspense boundary is required. ```tsx import { Suspense } from 'react' import { io } from 'next/cache' export default function Page() { return ( <Suspense fallback={<p>Loading...</p>}> <CurrentTime /> </Suspense> ) } async function CurrentTime() { await io() return <p>{new Date().toISOString()}</p> } ```

io() with Client Components example

In a Client Component, call io() with React's use hook before reading a synchronous source like Date.now(). Client Components prerender on the server during SSR, where the read would otherwise be included in the static shell. ```tsx 'use client' import { use } from 'react' import { io } from 'next/cache' export function CurrentTime() { use(io()) return <div>{Date.now()}</div> } ```

When io() is not needed

io() is not needed in two cases: (1) The component already uses a Request-time API like cookies() or headers(), where the request-time API itself is the suspension point. (2) The data comes from an awaited fetch or async database query wrapped in Suspense, where the await is the suspension point.

io() vs connection() difference

The connection() function excludes the code that follows it from the static shell, but it stays suspended until a full user navigation reaches the server, also blocking prefetches. io() suspends like any other asynchronous function, so the code after it can be wrapped in 'use cache' and prefetched and cached on the client. Prefer io() over connection(), and use connection() only when you need to wait for a real user request.

io() function signature

The io() function has the signature: function io(): Promise<void>. It accepts no parameters and returns a Promise<void>. With Cache Components enabled, awaiting this promise stops prerendering so the code that follows is excluded from the prerender output. In every other context (real requests, cache scopes, generateStaticParams, the browser, and routes without Cache Components), it resolves immediately.

io() use cases with synchronous values

Use await io() before reading synchronous values like new Date(), Math.random(), crypto.randomUUID(), or a synchronous database driver such as node:sqlite in a Server Component to keep it out of the static shell during prerendering.

io() version history

The io() function was added in Next.js v16.3.0.

ImageResponse constructor location

ImageResponse is imported from 'next/og'. In v14.0.0 it was moved from 'next/server' to 'next/og'.

ImageResponse constructor parameters

ImageResponse takes two parameters: element (ReactElement) and options object. The element parameter is the JSX content to render. The options object has the following properties: width (number, default 1200), height (number, default 630), emoji ('twemoji' | 'blobmoji' | 'noto' | 'openmoji', default 'twemoji'), fonts (array of {name: string, data: ArrayBuffer, weight: number, style: 'normal' | 'italic'}), debug (boolean, default false), status (number, default 200), statusText (string), and headers (Record<string, string>).

ImageResponse supported CSS properties

ImageResponse supports common CSS properties including flexbox and absolute positioning, custom fonts, text wrapping, centering, and nested images. Only flexbox and a subset of CSS properties are supported. Advanced layouts such as display: grid will not work. Refer to Satori's documentation for a complete list of supported HTML and CSS features.

ImageResponse bundle size limit

ImageResponse has a maximum bundle size of 500KB. The bundle size includes JSX, CSS, fonts, images, and any other assets. If the limit is exceeded, consider reducing the size of assets or fetching at runtime.

ImageResponse supported font formats

Only ttf, otf, and woff font formats are supported in ImageResponse. To maximize font parsing speed, ttf or otf are preferred over woff.

ImageResponse implementation details

ImageResponse uses @vercel/og, Satori, and Resvg to convert HTML and CSS into PNG.

ImageResponse in Route Handlers example

ImageResponse can be used in Route Handlers to generate images dynamically at request time. Example: import { ImageResponse } from 'next/og'; export async function GET() { try { return new ImageResponse( (<div style={{ height: '100%', width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', backgroundColor: 'white', padding: '40px', }}><div style={{ fontSize: 60, fontWeight: 'bold', color: 'black', textAlign: 'center', }}>Welcome to My Site</div><div style={{ fontSize: 30, color: '#666', marginTop: '20px', }}>Generated with Next.js ImageResponse</div></div>), { width: 1200, height: 630, } ) } catch (e) { console.log(`${e.message}`) return new Response(`Failed to generate the image`, { status: 500, }) } }

ImageResponse in metadata files

ImageResponse can be used in opengraph-image.tsx file to generate Open Graph images at build time or dynamically at request time.

ImageResponse custom fonts example

Custom fonts can be used in ImageResponse by providing a fonts array in the options. The font data should be read at module scope, not depending on request data. Example: import { ImageResponse } from 'next/og'; import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; export const alt = 'My site'; export const size = { width: 1200, height: 630, }; export const contentType = 'image/png'; const interSemiBold = await readFile(join(process.cwd(), 'assets/Inter-SemiBold.ttf')); export default async function Image() { return new ImageResponse((<div>...</div>), { ...size, fonts: [{ name: 'Inter', data: interSemiBold, style: 'normal', weight: 400, }], }); }

ImageResponse version history

v14.0.0: ImageResponse moved from next/server to next/og. v13.3.0: ImageResponse can be imported from next/server. v13.0.0: ImageResponse introduced via @vercel/og package.

next CLI basic usage

The Next.js CLI is invoked with `npx next [command] [options]` for npm, `pnpm next [command] [options]` for pnpm, `yarn next [command] [options]` for yarn, or `bunx next [command] [options]` for bun. With npm run, use `--` before CLI flags to forward them to next. Running `next` without a command is an alias for `next dev`.

next CLI global options

Global options for the next CLI are: `-h` or `--help` (shows all available options), `-v` or `--version` (outputs the Next.js version number).

next CLI commands overview

Available next CLI commands are: `dev` (starts Next.js in development mode with HMR and error reporting), `build` (creates optimized production build displaying route information), `start` (starts production mode after `next build`), `info` (prints system details for bug reporting), `telemetry` (enables/disables anonymous telemetry), `typegen` (generates TypeScript definitions for routes without full build), `upgrade` (upgrades to latest Next.js version), `experimental-analyze` (analyzes bundle output using Turbopack).

next dev options

Options for `next dev`: `-h, --help` (show options), `[directory]` (build directory, default: current), `--turbopack` / `--turbo` (force enable Turbopack, enabled by default), `--webpack` (use Webpack instead of Turbopack), `-p` or `--port <port>` (port number, default: 3000, env: PORT), `-H` or `--hostname <hostname>` (hostname, default: 0.0.0.0), `--experimental-https` (start with HTTPS and self-signed certificate), `--experimental-https-key <path>` (HTTPS key file path), `--experimental-https-cert <path>` (HTTPS certificate file path), `--experimental-https-ca <path>` (HTTPS certificate authority file path), `--experimental-upload-trace <traceUrl>` (report debugging trace to remote HTTP URL), `--experimental-cpu-prof` (enable CPU profiling, profiles saved to `.next-profiles/` on exit). Development builds output to `.next/dev` instead of `.next`, allowing concurrent `next dev` and `next build`.

next build options

Options for `next build`: `-h, --help` (show options), `[directory]` (build directory, default: current), `--turbopack` / `--turbo` (force enable Turbopack, enabled by default), `--webpack` (use Webpack), `-d` or `--debug` (verbose output showing rewrites, redirects, headers), `--profile` (enable production React profiling), `--no-lint` (disable linting; linting will be removed in Next 16), `--no-mangling` (disable name mangling for debugging), `--experimental-app-only` (build only App Router routes), `--experimental-build-mode [mode]` (experimental build mode with choices: "compile", "generate", default: "default"), `--debug-prerender` (debug prerender errors in development), `--debug-build-paths=<patterns>` (build only specific routes for debugging), `--experimental-cpu-prof` (enable CPU profiling, profiles saved to `.next-profiles/` on exit).

next start options

Options for `next start`: `-h` or `--help` (show options), `[directory]` (start directory, default: current), `-p` or `--port <port>` (port number, default: 3000, env: PORT), `-H` or `--hostname <hostname>` (hostname, default: 0.0.0.0), `--keepAliveTimeout <keepAliveTimeout>` (maximum milliseconds to wait before closing inactive connections), `--experimental-cpu-prof` (enable CPU profiling, profiles saved to `.next-profiles/` on exit).

next info options

Options for `next info`: `-h` or `--help` (show options), `--verbose` (collect additional information for debugging). The `next info` command prints system details including OS platform/arch/version, available memory/CPU cores, binaries (Node.js, npm, Yarn, pnpm), and relevant package versions.

next telemetry options

Options for `next telemetry`: `-h, --help` (show options), `--enable` (enable telemetry), `--disable` (disable telemetry). Next.js collects completely anonymous telemetry data about general usage, and participation is optional.

Give your agent this brain