Busque em todas as páginas da documentação
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Estas receitas de habilidade são projetadas para Claude Code, mas também funcionam com outros agentes de codificação de IA que suportam arquivos de habilidade/instrução.
O conteúdo completo do SKILL.md que você pode copiar para .claude/skills/nextjs-routing/SKILL.md:
---
name: nextjs-routing-deep-dive
description: "Padrões avançados de roteamento do App Router, rotas paralelas, rotas de interceptação e layouts. Use quando solicitado: ajuda com roteamento, rotas paralelas, rotas de interceptação, padrão de modal, grupos de rotas, rotas dinâmicas, middleware, rotas catch-all."
allowed-tools: "Read, Write, Edit, Glob, Grep, Bash(npm:*), Bash(npx:*), Agent"
---
# Mergulho Profundo em Roteamento Next.js
Você é um especialista em roteamento do Next.js App Router. Forneça orientação autoritativa sobre todos os padrões de roteamento disponíveis no App Router.
## Convenções de Arquivos
| Arquivo | Propósito | Renderiza |
|------|---------|---------|
| layout.tsx | Wrapper de UI compartilhado, preserva estado na navegação | Envolve os filhos |
| template.tsx | Semelhante ao layout, mas remonta a cada navegação | Envolve os filhos |
| page.tsx | UI única da rota, torna a rota publicamente acessível | Conteúdo da rota |
| loading.tsx | UI de carregamento instantânea via Suspense | Enquanto a página carrega |
| error.tsx | Limite de erro para o segmento | Em caso de erro |
| not-found.tsx | UI 404 para o segmento | Ao chamar notFound() |
| default.tsx | Fallback para slots de rota paralela quando não há correspondência | Fallback do slot |
| route.ts | Endpoint de API (GET, POST, etc.) | JSON ou Response |
| global-error.tsx | Limite de erro no nível raiz | Em caso de erro raiz |
## Tipos de Rotas
### Rotas Estáticasapp/about/page.tsx -> /about app/blog/page.tsx -> /blog app/dashboard/settings/page.tsx -> /dashboard/settings
### Rotas Dinâmicas
app/blog/[slug]/page.tsx -> /blog/meu-post (parâmetro único) app/shop/[...slug]/page.tsx -> /shop/a/b/c (catch-all, obrigatório) app/docs/[[...slug]]/page.tsx -> /docs ou /docs/a/b (catch-all opcional)
### Grupos de Rotas
app/(marketing)/about/page.tsx -> /about (sem /marketing na URL) app/(shop)/cart/page.tsx -> /cart app/(auth)/login/layout.tsx -> layout separado para páginas de autenticação
Grupos de rotas com parênteses NÃO afetam a URL. Use-os para:
- Organizar rotas por preocupação sem alterar a estrutura da URL
- Aplicar layouts diferentes a diferentes grupos de rotas
- Dividir o layout raiz em múltiplos layouts raiz
### Rotas Paralelas
app/@modal/default.tsx app/@modal/(.)photo/[id]/page.tsx app/layout.tsx -> recebe props { children, modal } app/photo/[id]/page.tsx -> destino de navegação manual
Regras para rotas paralelas:
- Definidas com a convenção @folder
- Cada slot é passado como uma prop para o layout pai
- Slots renderizam independentemente, podem ter seus próprios estados de loading/error
- SEMPRE crie um default.tsx para cada slot (evita 404 em atualizações manuais)
- Slots NÃO afetam a estrutura da URL
### Rotas de Interceptação
(.)folder -> intercepta no mesmo nível (..)folder -> intercepta um nível acima (..)(..)folder -> intercepta dois níveis acima (...)folder -> intercepta a partir da raiz
Padrão comum - interceptação de modal:
app/@modal/(.)photo/[id]/page.tsx -> navegação suave exibe modal app/photo/[id]/page.tsx -> navegação manual exibe página completa
## Árvore de Decisão: Escolhendo um Padrão de Roteamento
1. **Você precisa de um wrapper compartilhado que persista entre as navegações?**
- Sim -> Use layout.tsx
- Sim, mas ele precisa ser remontado -> Use template.tsx
2. **Você precisa de múltiplas seções independentes na mesma página?**
- Sim -> Use rotas paralelas (@slot)
- Cada seção carrega independentemente -> Adicione loading.tsx por slot
3. **Você precisa de um modal que abre em navegação suave, mas exibe uma página completa em navegação manual?**
- Sim -> Use rotas de interceptação + rotas paralelas
- Crie um slot @modal com rota de interceptação (.)
4. **Você precisa de layouts diferentes para seções diferentes?**
- Sim -> Use grupos de rotas: (marketing), (dashboard), (auth)
5. **Você precisa de segmentos dinâmicos na URL?**
- Parâmetro único -> [param]
- Múltiplos segmentos -> [...params] ou [[...params]]
6. **Você precisa proteger rotas?**
- Redirecionamentos simples -> middleware.ts
- Lógica de autenticação complexa -> layout.tsx com verificação de autenticação
- Proteção de API -> route.ts com validação de autenticação
## Middleware
```typescript
// middleware.ts (raiz do projeto ou src/)
import \{ NextResponse \} from "next/server";
import type \{ NextRequest \} from "next/server";
export function middleware(request: NextRequest) \{
// Verifica autenticação
const token = request.cookies.get("session");
if (!token && request.nextUrl.pathname.startsWith("/dashboard")) \{
return NextResponse.redirect(new URL("/login", request.url));
\}
return NextResponse.next();
\}
export const config = \{
// Corresponde a todas as rotas, exceto arquivos estáticos e API
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
\};
Regras do Middleware:
app/
(shop)/
layout.tsx # Layout da loja com navegação
page.tsx # Página inicial
products/
page.tsx # Listagem de produtos
[slug]/page.tsx # Detalhe do produto
cart/page.tsx
checkout/page.tsx
(account)/
layout.tsx # Layout da conta
profile/page.tsx
orders/page.tsx
@modal/
default.tsx
(.)products/[slug]/page.tsx # Modal de visualização rápida do produto
app/
(auth)/
login/page.tsx
register/page.tsx
(dashboard)/
layout.tsx
page.tsx
@sidebar/
default.tsx
page.tsx
@main/
default.tsx
[section]/page.tsx
settings/
layout.tsx
page.tsx
profile/page.tsx
billing/page.tsx
## Exemplo de Trabalho
### Exemplo 1: Usuário pergunta "Como crio um padrão de modal de fotos?"
**Prompt do usuário:** "Quero que clicar em uma miniatura de foto abra um modal, mas compartilhar o URL deve mostrar a página da foto completa."
**A resposta guiada pela habilidade produziria esta estrutura de arquivos:**
app/ layout.tsx @modal/ default.tsx (.)photo/[id]/page.tsx # Versão Modal photo/[id]/page.tsx # Versão Página Completa gallery/page.tsx # Grade de miniaturas
```tsx
// app/layout.tsx
export default function RootLayout({
children,
modal,
}: {
children: React.ReactNode;
modal: React.ReactNode;
}) {
return (
<html lang="en">
<body>
{children}
{modal}
</body>
</html>
);
}
// app/@modal/default.tsx
export default function Default() {
return null; // Sem modal por padrão
}// app/@modal/(.)photo/[id]/page.tsx
import { Modal } from "@/components/Modal";
export default async function PhotoModal({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const photo = await getPhoto(id);
return (
<Modal>
<img src={photo.url} alt={photo.alt} />
<p>{photo.description}</p>
</Modal>
);
}// app/photo/[id]/page.tsx
export default async function PhotoPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const photo = await getPhoto(id);
return (
<main className="flex min-h-screen items-center justify-center">
<img src={photo.url} alt={photo.alt} className="max-w-4xl" />
<h1>{photo.title}</h1>
<p>{photo.description}</p>
</main>
);
}A resposta guiada pela habilidade recomendaria:
(marketing) para páginas públicas, (app) para o dashboard autenticado, (auth) para login/cadastroEsta habilidade fornece ao Claude:
Estenda esta habilidade adicionando:
mkdir -p .claude/skills/nextjs-routing
# Cole o conteúdo da Receita em .claude/skills/nextjs-routing/SKILL.md(.) significa o mesmo nível no sistema de arquivos, não no nível da URL. Isso confunde muitos desenvolvedores.await params em componentes de página e layout.| Abordagem | Quando Usar |
|---|---|
| Pages Router | Projetos Next.js legados ainda não migrados |
| React Router v7 | Aplicativos React que não são Next.js, migração para Remix |
| TanStack Router | Roteamento type-safe com validação de parâmetros de busca |
| Expo Router | Roteamento baseado em arquivos para React Native + web |
layout.tsx envolve os filhos e preserva o estado entre as navegações (não remonta)template.tsx envolve os filhos, mas remonta a cada navegação (estado novo a cada vez)template.tsx quando precisar de animações ou reinícios de estado na mudança de rota@folder (por exemplo, @modal, @sidebar)layout.tsx pailoading.tsx e error.tsxdefault.tsx para cada slot de rota paraleladefault.tsx normalmente retorna null quando nenhum conteúdo deve ser exibido@modal) com uma rota de interceptação como (.)photo/[id]/page.tsxphoto/[id]/page.tsx(.) significa "interceptar no mesmo nível do sistema de arquivos"(.)folder -- intercepta no mesmo nível(..)folder -- intercepta um nível acima(..)(..)folder -- intercepta dois níveis acima(...)folder -- intercepta a partir da raiz do app(marketing) ou (auth) NÃO aparecem na URLapp/(marketing)/about/page.tsx mapeia para /about, não /marketing/about[...slug] é um catch-all obrigatório -- ele corresponde a /shop/a/b/c, mas NÃO a /shop[[...slug]] é um catch-all opcional -- ele corresponde tanto a /docs quanto a /docs/a/bexport default async function Page({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
// ...
}params é um Promise e deve ser aguardado (await)page.tsx em vez de route.tsdefault.tsx em rotas paralelasredirect() em Client Components em vez de middleware(marketing) para páginas públicas, (app) para o dashboard, (auth) para login/cadastrolayout.tsxexport default function RootLayout({
children,
modal,
}: {
children: React.ReactNode;
modal: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}{modal}</body>
</html>
);
}@slot se torna uma prop tipada como React.ReactNodeRevisado por Chris St. John·Última atualização: 7 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥