🚀 App Router - Fundamentos
Domine o novo sistema de roteamento do Next.js 13+ baseado em Server Components e aprenda como ele revoluciona o desenvolvimento web.
Por que isso é importante
O App Router é 70% mais rápido que o Pages Router tradicional e permite Server Components nativos, resultando em 50% menos JavaScript enviado ao cliente. Aplicações App Router carregam 2x mais rápido e têm melhor SEO, sendo adotado por 85% dos novos projetos Next.js.
Conceitos Fundamentais do App Router
Server Components (RSC):
Componentes que renderizam no servidor, reduzindo bundle JS e melhorando performance. Padrão no App Router.
Client Components:
Componentes que rodam no cliente, usando 'use client'. Necessários para interatividade, hooks e APIs do browser.
Nested Layouts:
Layouts aninhados que persistem entre navegações, mantendo estado e evitando re-renders desnecessários.
Streaming & Suspense:
Renderização progressiva com loading states, permitindo carregamento parcial de componentes pesados.
App Router vs Pages Router
✅ App Router (Recomendado)
- Server Components nativos
- Streaming e Suspense
- Layouts aninhados com persistência
- Loading & Error states automáticos
- Server Actions (formulários sem JS)
- Bundle JS menor (até 50%)
📄 Pages Router (Legacy)
- Client Components por padrão
- getServerSideProps / getStaticProps
- Layout único com _app.tsx
- Loading manual em cada página
- API Routes tradicionais
- Bundle JS maior
🚀 Estrutura do App Router
src/app/
├── globals.css # Estilos globais
├── layout.tsx # Layout raiz (obrigatório)
├── page.tsx # Página inicial (/)
├── loading.tsx # Loading UI
├── error.tsx # Error UI
├── not-found.tsx # 404 UI
│
├── dashboard/ # Rota /dashboard
│ ├── layout.tsx # Layout do dashboard
│ ├── page.tsx # /dashboard
│ ├── loading.tsx # Loading do dashboard
│ │
│ └── settings/ # Rota /dashboard/settings
│ ├── page.tsx # /dashboard/settings
│ └── loading.tsx # Loading das settings
│
└── api/ # API Routes
└── users/
└── route.ts # GET/POST /api/users✅ Vantagens Principais
- • Co-location: Loading e error states ficam próximos às páginas
- • Layouts aninhados: Múltiplos layouts que persistem na navegação
- • Streaming automático: Carregamento progressivo sem configuração
- • Server Components: Menos JavaScript no cliente
📄 Estrutura do Pages Router (Legacy)
src/pages/
├── _app.tsx # Layout global
├── _document.tsx # HTML document
├── index.tsx # Página inicial (/)
├── 404.tsx # Página 404
│
├── dashboard/ # Rota /dashboard
│ ├── index.tsx # /dashboard
│ └── settings.tsx # /dashboard/settings
│
└── api/ # API Routes
└── users.ts # GET/POST /api/users⚠️ Limitações
- • Um layout apenas: Definido em _app.tsx
- • Client-side por padrão: Mais JavaScript no cliente
- • Loading manual: Cada página precisa implementar
- • Data fetching complexo: getServerSideProps/getStaticProps
Server vs Client Components
🏗️ Server Components (Padrão)
Renderizam no servidor, reduzindo o bundle JavaScript enviado ao cliente.
// Server Component (padrão no App Router)
// Sem 'use client' = Server Component
export default async function HomePage() {
// ✅ Pode fazer fetch diretamente
const posts = await fetch('https://api.example.com/posts')
.then(res => res.json());
// ✅ Pode acessar variáveis de ambiente secretas
const secret = process.env.DATABASE_SECRET;
return (
<div>
<h1>Meu Blog</h1>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.content}</p>
</article>
))}
</div>
);
}✅ Quando usar:
- • Buscar dados
- • Acessar APIs backend
- • Renderizar conteúdo estático
- • SEO importante
💻 Client Components
Renderizam no cliente, necessários para interatividade e hooks do React.
'use client'; // ← Diretiva obrigatória
import { useState } from 'react';
export default function Counter() {
// ✅ Pode usar hooks do React
const [count, setCount] = useState(0);
// ✅ Pode usar APIs do browser
const handleClick = () => {
setCount(count + 1);
// ✅ Pode usar localStorage, window, etc.
localStorage.setItem('count', count.toString());
};
return (
<div>
<p>Contador: {count}</p>
{/* ✅ Pode usar event handlers */}
<button onClick={handleClick}>
Incrementar
</button>
</div>
);
}✅ Quando usar:
- • Interatividade (onClick, onChange)
- • Hooks do React (useState, useEffect)
- • APIs do browser (localStorage, window)
- • Bibliotecas client-side
Exemplo Prático: Blog com App Router
Vamos criar um blog simples que demonstra os conceitos do App Router:
1️⃣ Layout Raiz
import Link from 'next/link';
import './globals.css';
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Meu Blog',
description: 'Blog criado com Next.js App Router',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="pt-BR">
<body>
<header className="bg-bg-2 text-foreground p-4">
<h1>Meu Blog</h1>
<nav>
<Link href="/">Home</Link>
<Link href="/blog">Blog</Link>
<Link href="/sobre">Sobre</Link>
</nav>
</header>
<main className="container mx-auto p-4">
{children}
</main>
<footer className="bg-bg-2 text-foreground p-4 text-center">
© 2025 Meu Blog
</footer>
</body>
</html>
);
}2️⃣ Página Inicial (Server Component)
// Server Component - busca dados no servidor
export default async function HomePage() {
// ✅ Fetch direto no Server Component
const posts = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=5', {
next: { revalidate: 3600 } // Cache por 1 hora
}).then(res => res.json());
return (
<div>
<h1>Bem-vindo ao Meu Blog</h1>
<p>Últimos posts:</p>
<div className="grid gap-4">
{posts.map((post: any) => (
<article key={post.id} className="border p-4 rounded">
<h2 className="text-xl font-bold">{post.title}</h2>
<p className="text-fg-dim">{post.body.slice(0, 100)}...</p>
<a href={`/blog/${post.id}`} className="text-blue-500">
Ler mais →
</a>
</article>
))}
</div>
</div>
);
}3️⃣ Seção Blog com Loading
// Loading UI automático para /blog
export default function Loading() {
return (
<div className="animate-pulse">
<div className="h-8 bg-bg-3 rounded mb-4"></div>
<div className="space-y-4">
{[1,2,3].map(i => (
<div key={i} className="border p-4 rounded">
<div className="h-6 bg-bg-3 rounded mb-2"></div>
<div className="h-4 bg-bg-3 rounded w-3/4"></div>
</div>
))}
</div>
</div>
);
}Vantagens do App Router
- 🚀 Performance Superior:
Server Components reduzem bundle JS em até 50%
- 🔄 Streaming Nativo:
Carregamento progressivo automático com Suspense
- 🎨 Layouts Aninhados:
Múltiplos layouts que persistem na navegação
- ⚡ Loading States:
UI de carregamento automática para cada rota
- 🛡️ Error Boundaries:
Tratamento de erro granular por rota
- 📊 SEO Melhorado:
Server Components melhoram indexação
O que Você Conquistou
🎉 Fantástico! Você agora domina os fundamentos do App Router e entende como ele revoluciona o desenvolvimento Next.js.
- ✅ Diferenças fundamentais entre App Router e Pages Router
- ✅ Server vs Client Components e quando usar cada um
- ✅ Arquivos especiais (layout, page, loading, error)
- ✅ Streaming e Suspense para carregamento progressivo
- ✅ Exemplo prático de blog com App Router