Tipos de rotas | (), [] | Next.js
- Tipos de rotas |
(),[]| Next.js
No Next.js 16, o modelo principal de rotas é o App Router, baseado na pasta app.
A regra principal é:
Uma rota só vira uma página acessível no navegador quando existe um arquivo
page.tsxdentro da pasta.
Exemplo:
app/
page.tsx
Cria a rota:
/
Exemplo:
app/
produtos/
page.tsx
Cria a rota:
/produtos
Segundo a documentação oficial, uma página é uma UI renderizada em uma rota específica, criada com um arquivo page dentro do diretório app. (Next.js)
1. Rota estática
É a rota mais simples. O caminho da URL segue diretamente a estrutura das pastas.
Estrutura
app/
sobre/
page.tsx
URL gerada
/sobre
Exemplo
export default function SobrePage() {
return <h1>Sobre</h1>;
}
Use quando a rota tem um caminho fixo, como:
/
/sobre
/contato
/login
/dashboard
2. Rota aninhada
Uma rota aninhada é uma rota dentro de outra rota.
Estrutura
app/
dashboard/
usuarios/
page.tsx
URL gerada
/dashboard/usuarios
Exemplo
export default function UsuariosPage() {
return <h1>Usuários</h1>;
}
Use quando a URL representa hierarquia.
Exemplos:
/dashboard/usuarios
/dashboard/configuracoes
/produtos/categorias
/admin/permissoes
3. Rota dinâmica
Use quando parte da URL muda conforme um dado.
Estrutura
app/
produtos/
[id]/
page.tsx
URL gerada
/produtos/10
/produtos/25
/produtos/abc
O segmento dinâmico é criado usando colchetes, como [id] ou [slug]. (Next.js)
Exemplo
type Props = {
params: Promise<{
id: string;
}>;
};
export default async function ProdutoPage({ params }: Props) {
const { id } = await params;
return <h1>Produto {id}</h1>;
}
Use quando você precisa buscar algo por identificador.
Exemplos:
/produtos/123
/usuarios/42
/pedidos/abc-123
/posts/meu-primeiro-post
4. Rota dinâmica com slug
É uma rota dinâmica mais amigável para SEO.
Estrutura
app/
blog/
[slug]/
page.tsx
URL gerada
/blog/como-usar-nextjs
/blog/introducao-ao-react
Exemplo
type Props = {
params: Promise<{
slug: string;
}>;
};
export default async function BlogPostPage({ params }: Props) {
const { slug } = await params;
return <h1>Post: {slug}</h1>;
}
Use slug quando a URL precisa ser legível.
Bom:
/blog/como-criar-rotas-no-nextjs
Ruim para SEO:
/blog/123
5. Rota catch-all
Use quando você quer capturar vários segmentos da URL.
Estrutura
app/
docs/
[...slug]/
page.tsx
URLs aceitas
/docs/nextjs
/docs/nextjs/rotas
/docs/nextjs/rotas/dinamicas
Exemplo
type Props = {
params: Promise<{
slug: string[];
}>;
};
export default async function DocsPage({ params }: Props) {
const { slug } = await params;
return (
<div>
<h1>Documentação</h1>
<p>Caminho: {slug.join(" / ")}</p>
</div>
);
}
Use quando a profundidade da URL pode variar.
Exemplos:
/docs/backend/dotnet/signalr
/docs/frontend/nextjs/app-router
/categorias/eletronicos/notebooks/gamer
6. Rota catch-all opcional
Parecida com a anterior, mas também aceita a rota base.
Estrutura
app/
docs/
[[...slug]]/
page.tsx
URLs aceitas
/docs
/docs/nextjs
/docs/nextjs/rotas
Exemplo
type Props = {
params: Promise<{
slug?: string[];
}>;
};
export default async function DocsPage({ params }: Props) {
const { slug } = await params;
if (!slug) {
return <h1>Página inicial da documentação</h1>;
}
return <h1>Docs: {slug.join(" / ")}</h1>;
}
Use quando a página principal e as subpáginas podem compartilhar a mesma estrutura.
7. Route Groups
Route Groups servem para organizar o projeto sem alterar a URL.
Você cria uma pasta com parênteses:
(marketing)
Essa pasta não entra na URL. A documentação oficial descreve Route Groups como uma forma de organizar rotas sem afetar a estrutura da URL, além de permitir layouts por grupo. (Next.js)
Estrutura
app/
(site)/
sobre/
page.tsx
(admin)/
dashboard/
page.tsx
URLs geradas
/sobre
/dashboard
Repare que (site) e (admin) não aparecem na URL.
Uso comum
app/
(public)/
layout.tsx
page.tsx
sobre/
page.tsx
(auth)/
login/
page.tsx
cadastro/
page.tsx
(dashboard)/
layout.tsx
dashboard/
page.tsx
Use para separar áreas da aplicação.
Exemplo:
(public)
(auth)
(app)
(admin)
(marketing)
8. Layout por rota
O arquivo layout.tsx permite criar uma estrutura compartilhada entre páginas.
Estrutura
app/
dashboard/
layout.tsx
page.tsx
usuarios/
page.tsx
Exemplo
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div>
<aside>Menu lateral</aside>
<main>{children}</main>
</div>
);
}
Esse layout será usado em:
/dashboard
/dashboard/usuarios
Use para elementos persistentes:
Header
Sidebar
Menu lateral
Footer
Tabs
Área autenticada
9. Página de loading por rota
O arquivo loading.tsx cria uma UI de carregamento para uma rota.
Estrutura
app/
produtos/
loading.tsx
page.tsx
Exemplo
export default function Loading() {
return <p>Carregando produtos...</p>;
}
No App Router, loading.js envolve page.js, not-found.js e layouts aninhados em um boundary de Suspense. (Next.js)
Use quando a página faz busca de dados e você quer mostrar feedback visual.
10. Página de erro por rota
O arquivo error.tsx trata erros dentro de um segmento de rota.
Estrutura
app/
dashboard/
error.tsx
page.tsx
Exemplo
"use client";
export default function Error({
error,
reset,
}: {
error: Error;
reset: () => void;
}) {
return (
<div>
<h1>Erro ao carregar dashboard</h1>
<p>{error.message}</p>
<button onClick={reset}>Tentar novamente</button>
</div>
);
}
Ponto importante: error.tsx precisa ser Client Component, por isso usa:
"use client";
Use para tratar falhas específicas de uma área da aplicação.
11. Página 404 por rota
O arquivo not-found.tsx define a UI para quando uma rota ou recurso não for encontrado.
Estrutura
app/
produtos/
[id]/
not-found.tsx
page.tsx
Exemplo
import { notFound } from "next/navigation";
type Props = {
params: Promise<{
id: string;
}>;
};
export default async function ProdutoPage({ params }: Props) {
const { id } = await params;
const produto = null;
if (!produto) {
notFound();
}
return <h1>Produto {id}</h1>;
}
export default function ProdutoNotFound() {
return <h1>Produto não encontrado</h1>;
}
O Next.js possui convenções para not-found.js e global-not-found.js. O not-found.js é usado quando a função notFound é chamada dentro de um segmento de rota. (Next.js)
12. Global Not Found
Use global-not-found.tsx para definir uma página 404 global para rotas não encontradas.
Estrutura
app/
global-not-found.tsx
Exemplo
export default function GlobalNotFound() {
return (
<html>
<body>
<h1>404 - Página não encontrada</h1>
</body>
</html>
);
}
Diferença prática:
| Arquivo | Uso |
|---|---|
not-found.tsx | 404 dentro de um segmento específico |
global-not-found.tsx | 404 global para rotas não correspondidas |
13. Route Handlers
Route Handlers servem para criar endpoints HTTP dentro do Next.js.
São o equivalente moderno das antigas API Routes do pages.
A documentação oficial define Route Handlers como manipuladores customizados de request usando as APIs Web Request e Response, disponíveis dentro do diretório app. (Next.js)
Estrutura
app/
api/
produtos/
route.ts
URL gerada
/api/produtos
Exemplo GET
export async function GET() {
return Response.json([
{
id: 1,
nome: "Notebook",
},
]);
}
Exemplo POST
export async function POST(request: Request) {
const body = await request.json();
return Response.json(
{
message: "Produto criado",
data: body,
},
{
status: 201,
}
);
}
Métodos suportados
export async function GET() {}
export async function POST() {}
export async function PUT() {}
export async function PATCH() {}
export async function DELETE() {}
export async function HEAD() {}
export async function OPTIONS() {}
Use para:
/api/login
/api/produtos
/api/pedidos
/api/webhooks/stripe
/api/upload
14. Rota dinâmica em Route Handler
Você também pode criar endpoints dinâmicos.
Estrutura
app/
api/
produtos/
[id]/
route.ts
URL gerada
/api/produtos/10
Exemplo
type Context = {
params: Promise<{
id: string;
}>;
};
export async function GET(
request: Request,
context: Context
) {
const { id } = await context.params;
return Response.json({
id,
nome: "Produto exemplo",
});
}
Use quando o endpoint depende de um identificador.
Exemplos:
GET /api/produtos/10
PUT /api/produtos/10
DELETE /api/produtos/10
15. Rotas paralelas
Parallel Routes permitem renderizar páginas diferentes ao mesmo tempo dentro do mesmo layout.
Você cria slots usando @.
Estrutura
app/
dashboard/
layout.tsx
page.tsx
@analytics/
page.tsx
@team/
page.tsx
Segundo a documentação oficial, Parallel Routes permitem renderizar simultaneamente ou condicionalmente uma ou mais páginas dentro do mesmo layout, sendo úteis para dashboards e feeds dinâmicos. (Next.js)
Exemplo de layout
export default function DashboardLayout({
children,
analytics,
team,
}: {
children: React.ReactNode;
analytics: React.ReactNode;
team: React.ReactNode;
}) {
return (
<div>
<main>{children}</main>
<section>{analytics}</section>
<section>{team}</section>
</div>
);
}
Use quando uma tela tem regiões independentes.
Exemplos:
Dashboard com gráficos + lista de usuários
Feed + modal + sidebar
Tela administrativa com múltiplos painéis
16. Rotas interceptadas
Intercepting Routes servem para carregar uma rota dentro do layout atual, sem trocar totalmente o contexto visual.
São muito usadas para modal com URL.
A documentação oficial diz que rotas interceptadas permitem carregar uma rota de outra parte da aplicação dentro do layout atual, mascarando a URL no navegador. (Next.js)
Exemplo de cenário
Você tem:
/feed
/foto/123
Quando o usuário clica em uma foto dentro do feed, você quer abrir:
/foto/123
Mas visualmente como um modal sobre o feed.
Convenções
| Convenção | Significado |
|---|---|
(.) | mesmo nível |
(..) | um nível acima |
(..)(..) | dois níveis acima |
(...) | a partir da raiz do diretório app |
Exemplo estrutural
app/
feed/
page.tsx
@modal/
(..)foto/
[id]/
page.tsx
foto/
[id]/
page.tsx
Use quando precisa de:
Modal com URL compartilhável
Preview de item
Abrir detalhe sem perder contexto
Galeria de fotos
Produto em modal dentro de listagem
17. Private Folders
Pastas privadas usam _ no começo do nome.
Elas não viram rota.
Estrutura
app/
dashboard/
_components/
menu.tsx
page.tsx
URL gerada
/dashboard
A pasta _components não vira rota.
Use para organizar arquivos internos da rota:
_components
_lib
_utils
_hooks
_services
Exemplo:
app/
produtos/
_components/
produto-card.tsx
produto-list.tsx
page.tsx
18. Arquivos especiais de rota
No App Router, alguns nomes de arquivos têm significado especial.
| Arquivo | Função |
|---|---|
page.tsx | Cria uma página acessível por URL |
layout.tsx | Layout compartilhado entre rotas |
template.tsx | Similar ao layout, mas recria instância em navegações |
loading.tsx | UI de carregamento |
error.tsx | UI de erro |
not-found.tsx | UI de 404 por segmento |
global-not-found.tsx | UI global de 404 |
route.ts | Endpoint HTTP |
default.tsx | Fallback para Parallel Routes |
forbidden.tsx | UI para erro 403 |
unauthorized.tsx | UI para erro 401 |
A documentação oficial lista essas convenções de arquivos dentro do App Router, incluindo page, layout, loading, error, not-found, route, Parallel Routes e Intercepting Routes. (Next.js)
19. Diferença entre page.tsx e route.ts
| Arquivo | Serve para | Retorna |
|---|---|---|
page.tsx | Criar tela | JSX/React |
route.ts | Criar endpoint HTTP | Response/JSON/texto |
Página
app/produtos/page.tsx
export default function ProdutosPage() {
return <h1>Produtos</h1>;
}
Acessa no navegador:
/produtos
Endpoint
app/api/produtos/route.ts
export async function GET() {
return Response.json([
{
id: 1,
nome: "Notebook",
},
]);
}
Acessa como API:
/api/produtos
20. Organização recomendada
Para um projeto comum com área pública, login e dashboard:
app/
layout.tsx
page.tsx
(public)/
sobre/
page.tsx
contato/
page.tsx
(auth)/
login/
page.tsx
cadastro/
page.tsx
(app)/
dashboard/
layout.tsx
page.tsx
produtos/
page.tsx
[id]/
page.tsx
pedidos/
page.tsx
[id]/
page.tsx
api/
produtos/
route.ts
pedidos/
route.ts
URLs geradas:
/
/sobre
/contato
/login
/cadastro
/dashboard
/produtos
/produtos/123
/pedidos
/pedidos/456
/api/produtos
/api/pedidos
21. Pegadinhas importantes
Pasta sem page.tsx não vira página
Isto não cria rota acessível:
app/
produtos/
components/
produto-card.tsx
Para criar /produtos, precisa:
app/
produtos/
page.tsx
Route Group não entra na URL
app/
(admin)/
dashboard/
page.tsx
URL:
/dashboard
Não é:
/admin/dashboard
route.ts e page.tsx não devem disputar a mesma rota
Evite fazer isso:
app/
produtos/
page.tsx
route.ts
Na prática, se você quer tela, use:
app/produtos/page.tsx
Se você quer endpoint, prefira:
app/api/produtos/route.ts
Dynamic route retorna params
Para:
app/produtos/[id]/page.tsx
Você acessa:
const { id } = await params;
Catch-all retorna array
Para:
app/docs/[...slug]/page.tsx
A URL:
/docs/nextjs/rotas
Gera:
slug = ["nextjs", "rotas"];
22. Resumo rápido
| Tipo | Exemplo de pasta | URL |
|---|---|---|
| Estática | app/sobre/page.tsx | /sobre |
| Aninhada | app/dashboard/users/page.tsx | /dashboard/users |
| Dinâmica | app/produtos/[id]/page.tsx | /produtos/123 |
| Slug | app/blog/[slug]/page.tsx | /blog/meu-post |
| Catch-all | app/docs/[...slug]/page.tsx | /docs/a/b/c |
| Catch-all opcional | app/docs/[[...slug]]/page.tsx | /docs e /docs/a/b |
| Route Group | app/(admin)/dashboard/page.tsx | /dashboard |
| Route Handler | app/api/produtos/route.ts | /api/produtos |
| Parallel Route | app/dashboard/@analytics/page.tsx | Slot interno |
| Intercepting Route | app/feed/@modal/(..)foto/[id]/page.tsx | Modal com URL |