Fundamentos do Next.js 15
Rotas Estáticas e Dinâmicas com App Router
Aprenda sobre rotas estáticas e dinâmicas com app router
Módulo 1: Introdução e Setup do Next.js 15
Aula: Rotas Estáticas e Dinâmicas com App Router (Prática)
🚀 Introdução às Rotas no Next.js 15 com App Router
Olá! 👋 Nesta aula prática, vamos mergulhar no coração da navegação em aplicações Next.js 15: o sistema de roteamento. Com o App Router, o Next.js revolucionou a forma como definimos rotas, utilizando um sistema de arquivos intuitivo e poderoso.
Entender as rotas estáticas e dinâmicas é fundamental para construir qualquer aplicação web moderna, desde um blog simples até uma loja virtual complexa. As rotas permitem que os usuários naveguem entre diferentes páginas da sua aplicação, e o Next.js as torna incrivelmente fáceis de implementar e otimizar.
Nesta aula, você aprenderá a:
- Criar rotas estáticas com base na estrutura de pastas.
- Implementar rotas dinâmicas para lidar com URLs variáveis.
- Acessar parâmetros de rota em seus componentes.
- Usar rotas "catch-all" e "catch-all opcionais" para maior flexibilidade.
Prepare-se para codificar! 🧑💻
🧭 Entendendo as Rotas Estáticas
As rotas estáticas são as mais simples e diretas. Elas correspondem a um caminho URL fixo e são definidas pela estrutura de pastas dentro do diretório app/.
Como funcionam?
No App Router, cada pasta dentro de app/ que contém um arquivo page.tsx (ou .js, .jsx, .ts) se torna uma rota acessível. O nome da pasta define o segmento da URL.
Exemplo: Se você criar a seguinte estrutura de arquivos:
app/
├── page.tsx // Rota: /
├── about/
│ └── page.tsx // Rota: /about
└── dashboard/
└── page.tsx // Rota: /dashboard
app/page.tsxserá acessível em/.app/about/page.tsxserá acessível em/about.app/dashboard/page.tsxserá acessível em/dashboard.
É simples assim! ✨
Código de Exemplo:
// app/about/page.tsx
export default function AboutPage() {
return (
<main>
<h1>Sobre Nós</h1>
<p>Bem-vindo à página "Sobre Nós" da nossa aplicação Next.js!</p>
</main>
);
}Ao navegar para http://localhost:3000/about, você verá o conteúdo deste componente.
🛣️ Entendendo as Rotas Dinâmicas
As rotas dinâmicas são essenciais quando você precisa exibir conteúdo que varia com base em um identificador na URL. Pense em páginas de produtos, posts de blog, perfis de usuário, etc.
Como funcionam?
Você define um segmento de rota como dinâmico usando colchetes [] em torno do nome da pasta. O Next.js então captura o valor desse segmento na URL e o disponibiliza para o seu componente page.tsx através da prop params.
🧩 Rota Dinâmica Simples: [slug]
A sintaxe [slug] (ou qualquer outro nome que você dê, como [productId], [userId]) captura um único segmento da URL.
Exemplo:
Para um blog, você pode querer URLs como /blog/meu-primeiro-post ou /blog/sobre-nextjs.
app/
└── blog/
└── [slug]/
└── page.tsx // Rota: /blog/meu-primeiro-post
Código de Exemplo:
// app/blog/[slug]/page.tsx
interface BlogPostPageProps {
params: {
slug: string;
};
}
export default function BlogPostPage({ params }: BlogPostPageProps) {
return (
<main>
<h1>Detalhes do Post: {params.slug}</h1>
<p>Este é o conteúdo do post "{params.slug.replace(/-/g, ' ')}".</p>
</main>
);
}- Se você navegar para
http://localhost:3000/blog/meu-primeiro-post,params.slugserá"meu-primeiro-post". - Se navegar para
http://localhost:3000/blog/nextjs-e-o-app-router,params.slugserá"nextjs-e-o-app-router".
🗺️ Rota Dinâmica Catch-all: [...slug]
Às vezes, você precisa capturar múltiplos segmentos da URL. É aqui que entram as rotas "catch-all", definidas com [...slug]. Elas capturam todos os segmentos subsequentes da URL como um array de strings.
Exemplo:
Para documentação, você pode ter URLs como /docs/fundamentos/introducao ou /docs/api/autenticacao/oauth.
app/
└── docs/
└── [...slug]/
└── page.tsx // Rota: /docs/fundamentos/introducao
Código de Exemplo:
// app/docs/[...slug]/page.tsx
interface DocsPageProps {
params: {
slug: string[]; // Agora é um array de strings
};
}
export default function DocsPage({ params }: DocsPageProps) {
const path = params.slug.join(' / '); // Junta os segmentos para exibir
return (
<main>
<h1>Documentação em: {path}</h1>
<p>Você está navegando pela documentação em: /{params.slug.join('/')}</p>
</main>
);
}- Se você navegar para
http://localhost:3000/docs/fundamentos/introducao,params.slugserá["fundamentos", "introducao"]. - Se navegar para
http://localhost:3000/docs/api/autenticacao/oauth,params.slugserá["api", "autenticacao", "oauth"].
🌐 Rota Dinâmica Opcional Catch-all: [[...slug]]
A rota "catch-all opcional" [[...slug]] é similar à "catch-all", mas com uma diferença crucial: ela também corresponde à URL base sem nenhum segmento dinâmico. Ou seja, os segmentos são opcionais.
Exemplo:
Para uma página de categorias, onde /shop mostra todas as categorias e /shop/eletronicos/smartphones mostra subcategorias.
app/
└── shop/
└── [[...categoryPath]]/
└── page.tsx // Rota: /shop ou /shop/eletronicos/smartphones
Código de Exemplo:
// app/shop/[[...categoryPath]]/page.tsx
interface ShopPageProps {
params: {
categoryPath?: string[]; // Pode ser um array ou undefined
};
}
export default function ShopPage({ params }: ShopPageProps) {
const path = params.categoryPath ? params.categoryPath.join(' / ') : 'Todas as Categorias';
return (
<main>
<h1>Explorando Categoria: {path}</h1>
{params.categoryPath ? (
<p>Você está na categoria: /{params.categoryPath.join('/')}</p>
) : (
<p>Bem-vindo à página principal da loja! Explore nossas categorias.</p>
)}
</main>
);
}- Se você navegar para
http://localhost:3000/shop,params.categoryPathseráundefined. - Se navegar para
http://localhost:3000/shop/eletronicos,params.categoryPathserá["eletronicos"]. - Se navegar para
http://localhost:3000/shop/eletronicos/smartphones,params.categoryPathserá["eletronicos", "smartphones"].
🛠️ Exercícios Práticos
Agora é a sua vez de colocar a mão na massa! Siga os passos abaixo para criar um pequeno projeto Next.js e implementar as rotas que aprendemos.
Pré-requisitos:
Certifique-se de ter o Node.js (versão 18.17 ou superior) instalado em sua máquina.
Tarefas:
-
1. Configuração do Projeto Next.js
- Abra seu terminal.
- Crie um novo projeto Next.js usando o comando oficial.
npx create-next-app@latest my-nextjs-routes-app --ts --app --eslint --tailwind --src-dir false - Quando perguntado, escolha as opções padrão ou as que preferir (certifique-se de usar
--apppara o App Router e--tspara TypeScript). - Navegue para o diretório do projeto:
cd my-nextjs-routes-app. - Inicie o servidor de desenvolvimento:
npm run devouyarn dev. - Abra
http://localhost:3000no seu navegador para ver a página inicial.
-
2. Rota Estática Simples: Página de Configurações
- Crie a seguinte estrutura de pastas e arquivo:
app/dashboard/settings/page.tsx. - Dentro de
app/dashboard/settings/page.tsx, adicione o seguinte código:export default function DashboardSettingsPage() { return ( <main style={{ padding: '20px' }}> <h1>⚙️ Configurações do Dashboard</h1> <p>Esta é a página de configurações do seu painel de controle.</p> <p>URL: `/dashboard/settings`</p> </main> ); } - Verifique se a página está acessível em
http://localhost:3000/dashboard/settings.
- Crie a seguinte estrutura de pastas e arquivo:
-
3. Rota Dinâmica de Produto: Detalhes do Produto
- Crie a seguinte estrutura de pastas e arquivo:
app/products/[productId]/page.tsx. - Dentro de
app/products/[productId]/page.tsx, adicione o seguinte código:interface ProductPageProps { params: { productId: string; }; } export default function ProductPage({ params }: ProductPageProps) { return ( <main style={{ padding: '20px' }}> <h1>🛍️ Detalhes do Produto: {params.productId}</h1> <p>Você está visualizando o produto com ID: <strong>{params.productId}</strong>.</p> <p>Tente navegar para `/products/123` ou `/products/camiseta-nextjs`.</p> </main> ); } - Teste a rota navegando para
http://localhost:3000/products/123ehttp://localhost:3000/products/minha-camiseta-favorita.
- Crie a seguinte estrutura de pastas e arquivo:
-
4. Rota Dinâmica de Blog Catch-all: Artigos com Subcategorias
- Crie a seguinte estrutura de pastas e arquivo:
app/articles/[...slug]/page.tsx. - Dentro de
app/articles/[...slug]/page.tsx, adicione o seguinte código:interface ArticlesPageProps { params: { slug: string[]; }; } export default function ArticlesPage({ params }: ArticlesPageProps) { const fullPath = params.slug.join(' / '); return ( <main style={{ padding: '20px' }}> <h1>📝 Artigo em: {fullPath}</h1> <p>Este artigo está localizado em: <code>/articles/{params.slug.join('/')}</code></p> <p>Experimente: `/articles/programacao/javascript/nextjs-15` ou `/articles/noticias/ultimas-novidades`.</p> </main> ); } - Teste a rota com URLs como
http://localhost:3000/articles/tecnologia/frontend/reactehttp://localhost:3000/articles/politica/economia.
- Crie a seguinte estrutura de pastas e arquivo:
-
5. Rota Dinâmica Opcional Catch-all: Página de Portfólio
- Crie a seguinte estrutura de pastas e arquivo:
app/portfolio/[[...projectPath]]/page.tsx. - Dentro de
app/portfolio/[[...projectPath]]/page.tsx, adicione o seguinte código:interface PortfolioPageProps { params: { projectPath?: string[]; }; } export default function PortfolioPage({ params }: PortfolioPageProps) { const title = params.projectPath ? `Projeto: ${params.projectPath.join(' / ')}` : 'Meu Portfólio Principal'; return ( <main style={{ padding: '20px' }}> <h1>🖼️ {title}</h1> {params.projectPath ? ( <p>Detalhes do projeto: <code>/portfolio/{params.projectPath.join('/')}</code></p> ) : ( <p>Bem-vindo ao meu portfólio! Navegue pelos projetos.</p> )} <p>Experimente: `/portfolio` (sem path), `/portfolio/web/e-commerce` ou `/portfolio/mobile/app-social`.</p> </main> ); } - Teste a rota navegando para
http://localhost:3000/portfolio,http://localhost:3000/portfolio/design, ehttp://localhost:3000/portfolio/web/landing-page.
- Crie a seguinte estrutura de pastas e arquivo:
📚 Resumo e Próximos Passos
Parabéns! 🎉 Você concluiu a aula prática sobre rotas estáticas e dinâmicas no Next.js 15 App Router.
Pontos Chave que Aprendemos:
- Rotas Estáticas: Simplesmente crie pastas e um arquivo
page.tsxpara definir URLs fixas (ex:app/sobre/page.tsx->/sobre). - Rotas Dinâmicas Simples (
[slug]): Capturam um único segmento da URL (ex:app/produtos/[id]/page.tsx->/produtos/123). O valor é acessível viaparams.id. - Rotas Catch-all (
[...slug]): Capturam múltiplos segmentos da URL como um array (ex:app/docs/[...path]/page.tsx->/docs/guia/parte1). O valor é acessível viaparams.path. - Rotas Catch-all Opcionais (
[[...slug]]): Similar ao catch-all, mas o segmento dinâmico é opcional, permitindo que a rota base também seja acessada (ex:app/galeria/[[...fotos]]/page.tsx->/galeriaou/galeria/paisagens/montanhas). O valor é acessível viaparams.fotos(que pode serundefinedou um array).
Com este conhecimento, você já pode estruturar a navegação de qualquer aplicação Next.js de forma eficiente e flexível.
Próximos Passos: No próximo módulo, exploraremos como os layouts funcionam no App Router para compartilhar UI entre rotas, e como o Next.js lida com a busca de dados (data fetching) para tornar suas páginas interativas e dinâmicas.
Continue praticando e explorando a documentação oficial do Next.js para aprofundar seus conhecimentos! Até a próxima! 👋