Question presented to candidate:
"A user opens /products/999 and that product does not exist. How do you show a proper 'not found' page in the App Router, and how do you make sure search engines treat it as a 404?"
What a strong answer should cover:
- Call
notFound()fromnext/navigationin a Server Component, Server Function or Route Handler when the data is missing; it throws, so noreturnis needed and TypeScript narrows the value after it. - Next.js renders the nearest
not-found.tsxup the tree from where it was thrown; the rootapp/not-found.tsxalso handles every URL that matches no route. - Before streaming starts the response is a real 404; after a
loading.tsxor Suspense fallback has streamed, the status stays 200, and in both cases anoindexrobots tag is injected. - A
try/catcharound the call swallows it; rethrow withunstable_rethrow. not-found.tsxtakes no props, is a Server Component by default and can be async;global-not-found.tsx(experimental) covers apps with several root layouts.- Related:
forbidden()andunauthorized()work the same way for 403 and 401.
Clarifying questions expected:
- "Does the exact status code matter for analytics or compliance?" β then check before anything streams, or reject in Proxy.
- "Should a missing product show a product-specific message?" β then add a
not-found.tsxinside that segment.
Code / implementation expected: Yes β a data function that calls notFound(), root and segment not-found.tsx files, and a page that uses unstable_rethrow.