explica como o site da documentação obtém carregamentos rápidos de páginas estáticas enquanto mantém a funcionalidade do modo de edição do CMS
Este guia explica como o site da documentação obtém carregamentos rápidos de páginas estáticas enquanto mantém a funcionalidade do modo de edição do CMS.
Utilizamos duas rotas para o mesmo conteúdo:
app/
├── [...slug]/page.tsx # Produção: force-static (rápido)
└── preview/[...slug]/page.tsx # Modo de edição: force-dynamic (lê searchParams)
Um middleware de proxy reescreve transparentemente as solicitações de modo de edição:
Usuário solicita: /en/headless/quickstart?edit_mode=true
↓
Proxy detecta ?edit_mode=true
↓
Reescrita interna para: /preview/en/headless/quickstart?edit_mode=true
↓
Rota dinâmica renderiza com wrappers de edição
O usuário nunca vê /preview na sua URL - é uma reescrita interna.
// app/[...slug]/page.tsx
export const dynamic = 'force-static';
export const revalidate = 60;
export default async function Page({ params }) {
// Sem searchParams - a página é totalmente estática
// app/preview/[...slug]/page.tsx
export const dynamic = 'force-dynamic';
export default async function PreviewPage({ params, searchParams }) {
// searchParams disponível - pode detectar edit_mode
return <ParametricRoutePage params={params
?edit_mode=true da URL// src/proxy.ts
export const proxy = async (request: NextRequest) => {
const { pathname, searchParams } = request.nextUrl;
const editMode = searchParams.get('edit_mode');
| Cenário | Tempo de resposta | Renderização |
|---|---|---|
| Página de produção (em cache) | ~50-100ms | Estática da CDN |
| Página de produção (defasada) | ~50-100ms + atualização em segundo plano | Estática, depois ISR |
| Modo de edição | ~500-1500ms | SSR dinâmico |
A configuração revalidate = 60 habilita o ISR. Isso NÃO significa que as páginas são recomputadas a cada 60 segundos.
ISR usa um padrão stale-while-revalidate:
Chega uma requisição:
→ A página em cache tem < 60s? → Servir do cache (instantâneo)
→ A página em cache tem > 60s? → Servir cache obsoleto (instantâneo)
+ revalidar em segundo plano para a próxima requisição
Sem requisições = Sem recomputação. Nunca.
Exemplo:
A janela de 60 segundos é uma rede de segurança. Idealmente, usaríamos revalidação sob demanda via webhooks quando o conteúdo do CMS mudar.
| Caso de uso | URL | Rota utilizada |
|---|---|---|
| Navegação normal | /en/headless/quickstart | Estática |
| Construtor de templates do CMS | /en/headless/quickstart?edit_mode=true | Preview (via reescrita) |
| Preview de bloco de IA | /en/headless/quickstart?ai_preview=1 | Preview (via reescrita) |
A abordagem simples (sem force-static, sem rota de preview) funciona, mas é lenta:
// Abordagem simples - funciona, mas leva ~1-2s por requisição
export default async function Page({ params, searchParams }) {
return <ParametricRoutePage params={params} searchParams={searchParams} />;
}
Isso renderiza dinamicamente em cada requisição. Para um site de documentação com muitas páginas, isso significa:
A arquitetura de rotas duplas nos dá o melhor dos dois mundos: velocidade estática para leitores e funcionalidade dinâmica para editores.