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 App Router · all subjects

routing & navigation

7 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Dynamic segment params are a Promise

Dynamic segment parameters (params) are passed as a Promise. You must await params to access the segment values like username.

generateStaticParams must return at least one param

With Cache Components, returning an empty array from `generateStaticParams()` now errors with `empty-generate-static-params`. It must return at least one param so Next.js can prerender the route and validate it produces a non-empty static shell. Paths not returned are still served at request time with the static shell prerendered.

dynamicParams export not supported with Cache Components

Exporting `dynamicParams` fails the build when Cache Components is enabled with error: "Route segment config 'dynamicParams' is not compatible with nextConfig.cacheComponents". Params not returned by `generateStaticParams` are rendered on request. Use `notFound()` in the page to reject unknown params if needed.

Await params inside Suspense boundary

With Cache Components, pass the `params` promise into a `<Suspense>` boundary instead of awaiting at the top of the component. This allows unknown params to still prerender the static shell. The same applies to `usePathname()`, `useParams()`, `useSelectedLayoutSegment()`, and `useSelectedLayoutSegments()` hooks.

How to handle dynamic route segments like /blog/[slug]

In App Router with Cache Components: (1) `generateStaticParams()` must return at least one param to prerender. (2) Await the `params` promise inside a `<Suspense>` boundary rather than at the top of the component so unknown params can prerender. (3) Delete the `dynamicParams` export if present. (4) For params not returned by `generateStaticParams`, they render on-demand at request time with a prerendered static shell.

Example: Awaiting params in Suspense for dynamic routes

Before: `export default async function Page({ params }: { params: Promise<{ slug: string }> }) { const { slug } = await params; return <Post slug={slug} />; }`. After: `import { Suspense } from 'react'; export default function Page({ params }: PageProps<'/blog/[slug]'>) { return <Suspense fallback={<div>Loading...</div>}><Post params={params} /></Suspense>; }; async function Post({ params }: Pick<PageProps<'/blog/[slug]'>, 'params'>) { const { slug } = await params; ... }`.

Example: generateStaticParams returning at least one param

Before: `export async function generateStaticParams() { return []; }`. After: `export async function generateStaticParams() { const posts = await fetch('https://.../posts').then((res) => res.json()); return posts.slice(0, 1).map((post) => ({ slug: post.slug })); }`.

Give your agent this brain