Capítulo 122 de 456
Duas convenções para 404: not-found.js renderiza UI quando a função notFound() é chamada dentro de um segmento de rota; global-not-found.js (experimental) define uma página 404 para toda a aplicação a nível de roteamento, para URLs que não casam com nenhuma rota, sem depender de renderizar layout/page.
not-found.js: fica entre loading.js e page.js na hierarquia; é envolvido pelo <Suspense> de loading.js e pelo error boundary de error.js do mesmo segmento; segue o color scheme do SO (prefers-color-scheme), não lê tema da aplicação por padrão.global-not-found.js: bypassa a renderização normal da app; precisa importar seus próprios estilos globais/fontes/tema (não herda layout); precisa retornar documento HTML completo (<html>/<body>); útil quando há múltiplos root layouts ou root layout com dynamic segment top-level, tornando impossível compor um 404 único via layout.js + not-found.js.global-not-found.js requer flag experimental.globalNotFound: true em next.config.ts.not-found.js nem global-not-found.js aceitam props.200 para resposta streamed, 404 para resposta não-streamed; ambos incluem <meta name="robots" content="noindex"> automaticamente.app/not-found.js: além de capturar notFound() chamado explicitamente, também trata qualquer URL não casada em toda a aplicação (desde v13.3.0).import Link from 'next/link'
export default function NotFound() {
return (
<div>
<h2>Not Found</h2>
<p>Could not find requested resource</p>
<Link href="/">Return Home</Link>
</div>
)
}
not-found.js básico de segmento, Server Component por padrão.import './globals.css'
import { Inter } from 'next/font/google'
import type { Metadata } from 'next'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: '404 - Page Not Found',
description: 'The page you are looking for does not exist.',
}
export default function GlobalNotFound() {
return (
<html lang="en" className={inter.className}>
<body>
<h1>404 - Page Not Found</h1>
<p>This page does not exist.</p>
</body>
</html>
)
}
global-not-found.js importando explicitamente estilos globais e fonte, com metadata exportado (algo não suportado em global-error.jsx, mas suportado aqui).import { headers } from 'next/headers'
export default async function NotFound() {
const headersList = await headers()
const domain = headersList.get('host')
const data = await getSiteData(domain)
return <h2>Not Found: {data.name}</h2>
}
not-found.js como Server Component async buscando dado (ex. por domínio via headers()); para hooks de Client Component (usePathname), o fetch precisa migrar para o client.not-found.js de segmento herde tema global: usa prefers-color-scheme do SO; para tema explícito, use regra CSS de alta especificidade com seletor de tema, ou forneça markup próprio.global-not-found.js: ele bypassa a árvore normal de renderização, nada é herdado automaticamente.global-not-found.js sem ativar experimental.globalNotFound: feature não funciona sem a flag.usePathname (hook client) dentro do not-found.js Server Component: incompatível; mova o fetch de dado dependente de path para o client-side.| Version | Changes |
|---|---|
v15.4.0 | global-not-found.js introduzido (experimental) |
v13.3.0 | Root app/not-found passa a tratar URLs não casadas globalmente |
v13.0.0 | not-found introduzido |
not-found.js para 404 contextual dentro de um segmento (chamado via notFound()); use global-not-found.js só quando não dá pra compor um 404 único via layout normal (múltiplos root layouts, ou root layout com dynamic segment).global-not-found.js, diferente de global-error.jsx, suporta metadata/generateMetadata.noindex, então SEO não é prejudicado mesmo com status 200 no streaming.not-found.js na hierarquia via <Suspense>.