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-rendering/SKILL.md:
---
name: nextjs-rendering-strategies
description: "Profundo conhecimento em decisões de SSR, SSG, ISR, CSR e Partial Prerendering para Next.js. Use quando solicitado: estratégia de renderização, SSR vs SSG, estático vs dinâmico, PPR, pré-renderização parcial, generateStaticParams, ISR, CSR."
allowed-tools: "Read, Write, Edit, Glob, Grep, Bash(npm:*), Bash(npx:*), Agent"
---
# Estratégias de Renderização do Next.js
Você é um especialista em renderização do Next.js. Ajude os desenvolvedores a escolher e implementar a estratégia de renderização ideal para cada página.
## Fluxograma de Decisão de Renderização
Siga esta árvore de decisão para cada página:
1. **O conteúdo muda por usuário ou por solicitação?**
- Não -> Vá para o passo 2
- Sim -> Vá para o passo 4
2. **O conteúdo muda alguma coisa após a compilação?**
- Não -> **SSG** (Static Site Generation)
- Sim -> Vá para o passo 3
3. **Com que frequência ele muda?**
- Intervalo previsível -> **ISR** (Incremental Static Regeneration)
- Imprevisível (orientado a eventos) -> **ISR com revalidação sob demanda**
- Tempo real -> **SSR** ou **CSR** com polling
4. **A página tem partes estáticas e dinâmicas?**
- Sim -> **PPR** (Partial Prerendering) com Suspense
- Não, totalmente dinâmico -> **SSR** (Server-Side Rendering)
- Apenas interativo no cliente -> **CSR** (Client-Side Rendering)
## Referência de Estratégia
### SSG - Static Site Generation
**Quando:** O conteúdo é o mesmo para todos os usuários e não muda após a compilação (ou muda muito raramente).
**Exemplos:** Páginas de marketing, documentação, posts de blog, páginas legais.
```tsx
// app/about/page.tsx
// Esta página é automaticamente estática porque não tem funções dinâmicas
export default function AboutPage() \{
return <div>Conteúdo sobre nós...</div>;
\}
// Rotas dinâmicas com generateStaticParams
// app/blog/[slug]/page.tsx
export async function generateStaticParams() \{
const posts = await getAllPosts();
return posts.map((post) => (\{ slug: post.slug \}));
\}
export default async function BlogPost(\{
params,
\}: \{
params: Promise<\{ slug: string \}>;
\}) \{
const \{ slug \} = await params;
const post = await getPost(slug);
return <Article post=\{post\} />;
\}Desempenho: Melhor. Servido a partir da borda da CDN. Zero computação de servidor no momento da solicitação.
Quando: O conteúdo muda periodicamente, mas não precisa ser em tempo real.
Exemplos: Catálogo de produtos, artigos de notícias, páginas de preços, blog com atualizações.
// ISR baseado em tempo
// app/products/page.tsx
export const revalidate = 3600; // revalida a cada hora
export default async function ProductsPage() \{
const products = await getProducts();
return <ProductGrid products=\{products\} />;
\}
// ISR sob demanda via Server Action
// app/actions.ts
"use server";
import \{ revalidatePath, revalidateTag \} from "next/cache";
export async function updateProduct(id: string, data: ProductData) \{
await db.product.update(\{ where: \{ id \}, data \});
revalidateTag("products"); // invalida todas as páginas de produtos
\}Desempenho: Quase estático. A primeira solicitação após a revalidação aciona uma reconstrução; solicitações subsequentes servem a versão em cache.
Quando: O conteúdo é diferente por solicitação (específico do usuário, dados em tempo real, autenticação).
Exemplos: Dashboards, perfis de usuário, carrinhos de compras, resultados de pesquisa.
// app/dashboard/page.tsx
import \{ cookies \} from "next/headers";
export default async function DashboardPage() \{
// Usar cookies() torna esta rota dinâmica (SSR)
const cookieStore = await cookies();
const session = cookieStore.get("session");
const user = await getUser(session?.value);
const data = await getDashboardData(user.id);
return <Dashboard user=\{user\} data=\{data\} />;
\}Desempenho: Mais lento que estático. Cada solicitação atinge o servidor. Mitigar com streaming.
Quando: Conteúdo altamente interativo, dados em tempo real ou recursos que não precisam de SEO.
Exemplos: Painéis de administração, ferramentas de visualização de dados, editores colaborativos, mapas.
"use client";
import useSWR from "swr";
export default function LiveDashboard() \{
const \{ data, error, isLoading \} = useSWR(
"/api/metrics",
fetcher,
\{ refreshInterval: 5000 \} // poll a cada 5 segundos
);
if (isLoading) return <DashboardSkeleton />;
if (error) return <ErrorMessage error=\{error\} />;
return <MetricsDisplay data=\{data\} />;
\}Desempenho: Shell inicial mais rápido (se combinado com shell SSR), mas o conteúdo aparece após o carregamento do JS e a conclusão das buscas.
Quando: Uma página tem conteúdo estático e dinâmico. O shell estático deve ser instantâneo, com partes dinâmicas sendo transmitidas.
Exemplos: Páginas de produtos (descrição estática, preço/estoque dinâmico), feeds sociais (layout estático, conteúdo dinâmico), dashboards (navegação estática, dados dinâmicos).
// next.config.ts
const config = \{ experimental: \{ ppr: true \} \};
// app/product/[id]/page.tsx
import \{ Suspense \} from "react";
export default async function ProductPage(\{
params,
\}: \{
params: Promise<\{ id: string \}>;
\}) \{
const \{ id \} = await params;
const product = await getCachedProduct(id); // estático, em cache
return (
<main>
\{/* Shell estático - pré-renderizado no tempo de compilação */\}
<h1>\{product.name\}</h1>
<p>\{product.description\}</p>
<StaticImages images=\{product.images\} />
\{/* Buracos dinâmicos - transmitidos no momento da solicitação */\}
<Suspense fallback=\{<PriceSkeleton />\}>
<LivePrice productId=\{id\} />
</Suspense>
<Suspense fallback=\{<StockSkeleton />\}>
<StockStatus productId=\{id\} />
</Suspense>
<Suspense fallback=\{<ReviewsSkeleton />\}>
<Reviews productId=\{id\} />
</Suspense>
</main>
);
\}Desempenho: O melhor dos dois mundos. Shell estático servido da CDN instantaneamente, conteúdo dinâmico transmitido.
| Estratégia | TTFB | FCP | SEO | Atualidade | Custo do Servidor |
|---|---|---|---|---|---|
| SSG | Mais Rápido | Mais Rápido | Excelente | Apenas tempo de compilação | Nenhum |
| ISR | Rápido | Rápido | Excelente | Periódico ou sob demanda | Baixo |
| SSR | Moderado | Moderado | Excelente | Tempo real | Alto |
| CSR | Rápido (shell) | Lento (conteúdo) | Ruim (sem shell SSR) | Tempo real | Baixo (apenas API) |
| PPR | Mais Rápido (shell) | Rápido (shell) + streaming | Excelente | Híbrido | Moderado |
Estas funções e APIs tornam uma rota dinâmica (SSR em vez de SSG):
cookies() - Leitura de cookiesheaders() - Leitura de cabeçalhos de solicitaçãosearchParams - Uso de parâmetros de pesquisafetch(url, { cache: "no-store" }) - Fetch sem cacheexport const dynamic = "force-dynamic" - Opt-in explícitogenerateStaticParams para rotas dinâmicas (causa SSR sob demanda)revalidate muito baixo (efetivamente se torna SSR)Promise.all ou streaming)
## Exemplo de Trabalho
### Exemplo 1: Usuário pergunta "Esta página deve ser SSR ou SSG?"
**Prompt do usuário:** "Tenho uma página de detalhes do produto em /products/[slug]. As informações do produto raramente mudam, mas o preço é atualizado algumas vezes por dia."
**Resposta guiada pela habilidade:**
A página do produto deve usar **ISR com revalidação sob demanda** para as informações do produto, combinado com **streaming** para o preço dinâmico:
```tsx
// app/products/[slug]/page.tsx
import { Suspense } from "react";
export async function generateStaticParams() {
const products = await getTopProducts(100); // Pré-compila os 100 principais
return products.map((p) => ({ slug: p.slug }));
}
export const revalidate = 86400; // Recompila as informações do produto diariamente
export default async function ProductPage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const product = await getProduct(slug);
return (
<main>
<h1>{product.name}</h1>
<p>{product.description}</p>
<Suspense fallback={<span>Carregando preço...</span>}>
<LivePrice slug={slug} />
</Suspense>
</main>
);
}
Mais uma Server Action para revalidação sob demanda quando os produtos são editados no CMS.
A resposta guiada pela habilidade incluiria:
ppr: true em next.config.tsEsta habilidade fornece ao Claude um framework de decisão estruturado:
mkdir -p .claude/skills/nextjs-rendering
# Cole o conteúdo da Receita em .claude/skills/nextjs-rendering/SKILL.mdcookies() em um componente profundamente aninhado força toda a rota a SSR. Use limites de Suspense e PPR para isolar partes dinâmicas.generateStaticParams não garante SSG - Se o componente da página usar APIs dinâmicas, as páginas geradas ainda serão SSR.experimental.ppr e pode mudar em lançamentos futuros.| Abordagem | Quando Usar |
|---|---|
| Astro | Sites ricos em conteúdo com interatividade mínima |
| Remix | SSR completo com carregamento de dados aninhado e mutações |
| Gatsby | Geração estática no tempo de compilação com camada de dados GraphQL |
| Nuxt.js | Equivalente Vue.js com estratégias de renderização semelhantes |
revalidateTag ou revalidatePath acionado por uma Server Action ou webhookcookies() -- leitura de cookiesheaders() -- leitura de cabeçalhos de solicitaçãosearchParams -- uso de parâmetros de pesquisafetch(url, { cache: "no-store" }) -- fetch sem cacheexport const dynamic = "force-dynamic" -- opt-in explícitogenerateStaticParams apenas pré-gera os parâmetros; a estratégia de renderização depende do que o componente fazexperimental: { ppr: true } em next.config.tsexport default async function ProductPage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
// ...
}params é uma Promise e deve ser aguardadoPromise.all ou streaming)cookies() ou headers() quando não são necessários, forçando toda a rota a ser dinâmicarevalidate = 3600 em uma página não afeta outras páginasRevisado por Chris St. John·Última atualização: 7 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥