Este repositório tem como objetivo fornecer uma documentação prática e detalhada dos conceitos avançados em Next.js 14, incluindo exemplos e anotações das principais funcionalidades. As lições abordam desde o básico até conceitos mais avançados, permitindo uma compreensão completa do sistema de roteamento do Next.js.
- Em Next.js, rotas são criadas automaticamente com base na estrutura de arquivos dentro do diretório
app
(oupages
para versões anteriores). - Cada arquivo JavaScript ou TypeScript em
app
representa uma rota.
-
Páginas:
- Cada componente de página no diretório
app
representa uma rota. - Exemplo:
app/about/page.js
cria a rota/about
.
- Cada componente de página no diretório
-
Layouts:
- Layouts permitem definir uma estrutura comum para várias páginas.
- Utilizar
app/layout.js
para definir um layout que envolve páginas. - Layouts são aplicados em múltiplas páginas e podem incluir cabeçalhos, rodapés, etc.
-
Criação de Rotas Dinâmicas:
- Utilizar colchetes
[param]
para criar rotas dinâmicas. - Exemplo:
app/posts/[id]/page.js
cria uma rota dinâmica para/posts/:id
.
- Utilizar colchetes
-
Rotas Dinâmicas Aninhadas:
- Organizar rotas dinâmicas com subpastas e arquivos.
- Exemplo:
app/users/[userId]/posts/[postId]/page.js
para uma rota aninhada.
- Grupos de Rotas:
- Usando colchetes: agrupar rotas usando colchetes em pastas para aplicar uma estrutura de URL. Exemplo:
app/dashboard/[section]/page.js
permite/dashboard/:section
. - Usando parênteses: para organizar rotas e layouts em grupos sem afectar a url. Exemplo:
app/(admin)/dashboard/page.js
cria uma rota/dashboard
dentro do grupo(admin)
.
- Usando colchetes: agrupar rotas usando colchetes em pastas para aplicar uma estrutura de URL. Exemplo:
-
Componente
Link
:- Utilizar o componente
Link
para navegação entre páginas. - Exemplo:
import Link from 'next/link'; function Navigation() { return ( <nav> <Link href="/about">About</Link> <Link href="/contact">Contact</Link> </nav> ); }
- Utilizar o componente
-
Navegação Programática:
- Usar
router.push
erouter.replace
para navegação programática. - Exemplo:
import { useRouter } from 'next/router'; function RedirectButton() { const router = useRouter(); return ( <button onClick={() => router.push('/home')}> Go to Home </button> ); }
- Usar
-
Páginas de Erro:
- Criar páginas de erro personalizadas para códigos de status como 404 e 500.
- Exemplo:
app/404/page.js
para uma página 404 personalizada.
-
Tratamento de Erros:
- Implementar lógica para lidar com erros específicos dentro de rotas dinâmicas.
- Exemplo: Exibir mensagens de erro ou páginas de fallback.
-
Rotas Paralelas:
- Utilizar rotas paralelas para renderizar múltiplos componentes em uma única página.
- Exemplo:
app/dashboard/page.js
eapp/dashboard/notifications/page.js
para exibir notificações paralelas.
-
Interceptação de Rotas:
- Interceptar e manipular rotas antes de serem exibidas.
- Exemplo: Usar interceptadores para lógica de autenticação ou redirecionamentos.
-
Manipuladores de Rotas:
- Definir manipuladores para alterar o comportamento das rotas, como parâmetros de consulta ou autenticação.
- Exemplo: Manipular os parâmetros da URL para filtrar conteúdo.
-
Middleware:
- Utilizar middleware para lógica que deve ser executada em todas ou algumas rotas.
- Exemplo:
middleware.ts
para autenticação ou validação de requisições.
Por padrão, o Next.js pré-renderiza cada página. Isso significa que o Next.js gera HTML para cada página com antecedência, em vez de ter tudo feito pelo JavaScript do lado do cliente.
-
Renderização no Lado do Servidor (SSR): As páginas são geradas no servidor a cada requisição. Isso garante que os dados estejam sempre atualizados.
-
Renderização Estática (SSG): As páginas são geradas no momento da construção e são servidas como arquivos estáticos. Ideal para páginas que não mudam frequentemente.
-
Renderização no Lado do Cliente (CSR): O conteúdo é carregado e renderizado no cliente. Isso é útil para interações dinâmicas e dados que mudam frequentemente.
Por padrão, o Next.js usa Server Components. Permitem que você escreva UI que pode ser renderizada e, opcionalmente, armazenada em cache no servidor. No Next.js, o trabalho de renderização é dividido ainda mais por segmentos de rota para habilitar streaming e renderização parcial, e há três estratégias diferentes de renderização de servidor:
-
Renderização estática (padrão): as rotas são renderizadas no momento da construção (build) ou em segundo plano após a revalidação dos dados.
-
Renderização dinâmica: as rotas são renderizadas para cada usuário no momento da solicitação. Funções dinâmicas dependem de informações que só podem ser conhecidas no momento da solicitação, como cookies do usuário, cabeçalhos de solicitações atuais ou parâmetros de pesquisa da URL.
-
Streaming: permite que você renderize progressivamente a UI do servidor. O trabalho é dividido em pedaços e transmitido para o cliente conforme fica pronto. Isso permite que o usuário veja partes da página imediatamente, antes que todo o conteúdo tenha terminado de renderizar.
Os Client Components permitem que você escreva uma IU interativa que é pré-renderizada no servidor e pode usar JavaScript do cliente para executar no navegador.
Há algumas vantagens em fazer o trabalho de renderização no cliente, incluindo:
-
Interatividade: os componentes do cliente podem usar ouvintes de estado, efeitos e eventos, o que significa que eles podem fornecer feedback imediato ao usuário e atualizar a interface do usuário.
-
APIs do navegador: os componentes do cliente têm acesso às APIs do navegador, como geolocalizaçãoou localStorage.
Ao construir aplicativos React, você precisará considerar quais partes do seu aplicativo devem ser renderizadas no servidor ou no cliente.
A pré-renderização parcial (PPR) permite combinar componentes estáticos e dinâmicos na mesma rota. Durante a construção, o Next.js pré-renderiza o máximo possível da rota. Se um código dinâmico for detectado, como a leitura da solicitação de entrada, você pode encapsular o componente relevante com um React Suspense. O fallback da Suspense será então incluído no HTML pré-renderizado.
Data Fetching refere-se ao processo de recuperação de dados de uma fonte externa, como uma API ou um banco de dados, e a disponibilização desses dados para serem usados na renderização das páginas da aplicação. O Next.js 14 fornece várias abordagens para fazer isso de maneira eficiente.
Este componente buscará e exibirá uma lista de posts de blog. A resposta de fetch será automaticamente armazenada em cache.
export default async function Page() {
let data = await fetch('https://api.vercel.app/blog')
let posts = await data.json()
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
Se você não estiver usando nenhuma função dinâmica em nenhum outro lugar nesta rota, ela será pré-renderizada durante next build
uma página estática.
Se você não quiser armazenar em cache a resposta de fetch, você pode fazer o seguinte:
let data = await fetch('https://api.vercel.app/blog', { cache: 'no-store' })
No entanto, ainda há casos em que a busca de dados do lado do cliente faz sentido. Nesses cenários, você pode chamar manualmente fetch
um useEffect
ou recorrer a bibliotecas React populares na comunidade (como SWR
ou React Query
) para busca de dados.
'use client'
import { useState, useEffect } from 'react'
export function Posts() {
const [posts, setPosts] = useState(null)
useEffect(() => {
async function fetchPosts() {
let res = await fetch('https://api.vercel.app/blog')
let data = await res.json()
setPosts(data)
}
fetchPosts()
}, [])
if (!posts) return <div>Loading...</div>
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}