ADR-001: Adoção do App Router (Next.js 15)
| Campo | Valor |
|---|---|
| Status | ✅ Accepted |
| Data | 2024-Q1 |
| Decisores | Time de desenvolvimento |
| Impacto | Alto — afeta toda a estrutura de rotas, fetching de dados e renderização |
Contexto
O projeto foi iniciado em um momento em que o Next.js havia estabilizado o App Router como abordagem recomendada, enquanto o Pages Router continuava disponível para projetos legados. A equipe precisava escolher entre:
- Pages Router — abordagem familiar, estável e com ampla documentação histórica, mas sem suporte a React Server Components (RSC) ou Streaming.
- App Router — abordagem nova, com curva de aprendizado maior, mas representando a direção estratégica do framework e do ecossistema React.
Como o projeto era novo (sem legado de código), a migração forçada não era um problema — o custo de adoção do App Router era o mesmo de qualquer outra escolha arquitetural feita no início.
A questão central era: vale a pena adotar uma tecnologia mais nova e com menos exemplos disponíveis para um e-commerce em produção?
Decisão
Adotamos o App Router com React Server Components como padrão em todo o projeto.
Toda a estrutura de rotas vive sob app/, seguindo as convenções de arquivo do App Router (page.tsx, layout.tsx, loading.tsx, error.tsx, not-found.tsx). Server Actions são utilizadas para mutações de formulário (checkout, criação de produto no admin) onde faz sentido reduzir a superfície de API.
Justificativa
React Server Components (RSC)
RSC permite que componentes de servidor busquem dados diretamente — sem getServerSideProps, sem useEffect, sem estado de carregamento intermediário. Para páginas de produto e listagem de catálogo, isso significa que o HTML com conteúdo chega completo na primeira resposta HTTP, melhorando o Core Web Vitals (LCP, FCP) e a indexabilidade por mecanismos de busca.
Streaming com Suspense
O App Router suporta entrega incremental de HTML via <Suspense>. Seções lentas (ex.: recomendações de produtos baseadas em histórico, cálculo de frete) podem exibir um esqueleto imediatamente enquanto o dado real ainda está sendo buscado no servidor, sem bloquear o restante da página.
Layouts aninhados e colocação de dados
O sistema de layout.tsx aninhados elimina re-montagens desnecessárias de componentes de shell (header, footer, sidebar do admin) durante navegações. A colocação de dados — buscar exatamente o dado necessário no componente que o usa, sem prop drilling — torna o código mais legível e mais fácil de depurar.
Preparação para o futuro
O Pages Router foi marcado como "não haverá novos recursos" pelo time do Next.js. Adotar o App Router desde o início evita uma migração futura custosa.
Consequências
Positivas
- Melhor SEO e performance — conteúdo de produto renderizado no servidor, sem dependência de JavaScript do cliente para indexação.
- Streaming e Suspense — UX mais responsiva em conexões lentas.
- Layouts aninhados — sidebar do admin, header da loja e breadcrumbs gerenciados por layout, não por componente individual.
- Server Actions — formulários de checkout e criação de produto funcionam sem criar um Route Handler separado para cada mutação simples.
- Melhor segurança por padrão — segredos de API (MercadoPago, Stripe, banco) ficam exclusivamente em Server Components; nunca chegam ao bundle do cliente.
Negativas / Ressalvas
- Curva de aprendizado — a distinção entre
"use client"e Server Components é não intuitiva para desenvolvedores vindos do Pages Router. Erros comuns: tentar usar hooks em Server Components, importar bibliotecas que acessamwindowem RSC. - Ecossistema ainda em maturação — algumas bibliotecas de UI populares precisaram de wrappers
"use client"específicos para funcionar (ex.: wrappers do Radix UI e do Puck Editor). - Server Actions em produção — requerem atenção a CSRF (Next.js protege automaticamente com
Originheader em produção, mas isso precisa ser documentado para novos contribuidores). - Debugging mais complexo — o modelo mental de "dois ambientes" (servidor e cliente) requer atenção extra ao rastrear erros que cruzam essa fronteira.
Alternativas consideradas
Pages Router (descartado)
Motivo: Sem suporte a React Server Components nem Streaming. Toda a busca de dados continuaria acontecendo via getServerSideProps (deprecado na direção estratégica do Next.js) ou no cliente com useEffect (pior para SEO e performance). A escolha do Pages Router significaria adotar uma tecnologia já em modo de manutenção.
Remix (descartado)
Motivo: Ecossistema significativamente menor que Next.js à época da decisão, com menos bibliotecas de terceiros testadas em conjunto. A curva de aprendizado seria similar à do App Router, sem a vantagem do suporte à comunidade e documentação extensos do Next.js. A integração com o Prisma e os SDKs de pagamento também é mais documentada no contexto do Next.js.
Referências
- Next.js App Router Documentation
- React Server Components RFC
- ADR-002 — Prisma + MySQL (decisão relacionada — como o fetching de dados no servidor se conecta ao Prisma)