Demo
Página de demonstração
O que é SSR?
Esta página demo não é uma ferramenta final para usuários, mas uma pequena rota de referência para renderização no servidor. Ela mostra como uma página do Next.js App Router pode buscar dados no servidor, renderizar o resultado no primeiro HTML e carregar os textos traduzidos do locale atual. Por isso é útil para verificar infraestrutura compartilhada: variáveis de ambiente, requisições assinadas no servidor, formato da resposta da API, roteamento por locale e carregamento de traduções. Se esta página funciona, o caminho básico de SSR está saudável antes de depurar uma ferramenta mais complexa. Se falha, o problema provavelmente está na configuração comum do servidor ou na conectividade com a API. Ela deve permanecer simples para funcionar como smoke test após deploys e mudanças de framework.
Como usar
Como usar
- A página chama automaticamente a API de back-end no servidor
- O HTML inclui conteúdo pré-renderizado, sem necessidade de requisição do cliente
- Visualize os dados retornados pela API
- Ideal para páginas que precisam de otimização de SEO
Notas de desenvolvimento
- Use esta página como smoke test para SSR, carregamento de locale, requisições de servidor assinadas e conectividade de API.
- Se esta página falhar, verifique a configuração compartilhada do servidor antes de depurar uma página de ferramenta específica.
Casos de uso
Princípio técnico
Esta página Demo é construída sobre o Next.js 16 App Router e usa renderização no lado do servidor (SSR) por padrão. Quando um usuário solicita a página, o servidor Node.js primeiro executa o componente React, chama a API de back-end para obter os dados e então retorna o HTML totalmente renderizado ao navegador em uma única resposta. O navegador começa a analisar e renderizar o HTML imediatamente, então os usuários veem o conteúdo completo no primeiro quadro sem esperar que o JavaScript seja baixado e executado. Isso contrasta fortemente com a renderização no lado do cliente (CSR) tradicional. No CSR, o servidor retorna apenas um shell HTML quase vazio e um link de JS; o navegador precisa baixar o pacote JS, executar a inicialização do framework, chamar APIs para buscar dados e só então renderizar a página. Do ponto de vista do usuário, isso é 'uma tela em branco por um tempo', e é ainda pior para rastreadores de mecanismos de busca — a maioria dos rastreadores não executa JavaScript e só vê o shell vazio. Após o SSR, o Next.js também injeta um trecho de JavaScript para realizar a 'hidratação': associar o DOM existente à árvore de componentes React e vincular event listeners para que a página se torne interativa. O fluxo completo é: análise HTML → carregamento CSS → download JS → hidratação → página interativa. Entre os três Core Web Vitals, LCP (Largest Contentful Paint) e CLS (Cumulative Layout Shift) geralmente são melhores sob SSR, enquanto INP (Interaction to Next Paint) depende da velocidade de hidratação e da qualidade da implementação dos handlers de eventos.
- Next.js App Router: páginas no App Router são Server Components por padrão, executando no servidor e retornando HTML automaticamente sem configuração extra.
- SSR vs CSR: SSR entrega primeira pintura rápida e amigabilidade ao SEO ao custo de recursos do servidor; CSR se adequa a dashboards internos e outros cenários interativos que não precisam de SEO.
- Fluxo da primeira pintura: análise HTML → carregamento e renderização CSS → download e execução de JS → hidratação React → página interativa; cada etapa afeta o LCP.
- Amigabilidade ao rastreamento SEO: rastreadores mainstream como Googlebot e Bingbot leem o texto HTML diretamente; a saída SSR com conteúdo completo garante cobertura de rastreamento.
- Limites dos Web Vitals: LCP < 2,5s, INP < 200ms, CLS < 0,1 são os limites 'bom' recomendados pelo Google; SSR facilita atingir LCP e CLS.
- Requisições assinadas: a página Demo chama a API de back-end pelo serverApiFetch no servidor, carregando automaticamente X-Timestamp, X-Nonce e X-Sign para completar a autenticação.
Exemplos
SSR (Server-Side Rendering)
// app/page.tsx (Server Component padrão)
export default async function Page() {
const data = await fetch('/api/info').then(r => r.json());
return <div>{data.title}</div>;
}
// O HTML já contém diretamente <div>conteúdo real</div>CSR (Client-Side Rendering)
'use client';
import { useEffect, useState } from 'react';
export default function Page() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/api/info').then(r => r.json()).then(setData);
}, []);
return <div>{data?.title || 'Loading...'}</div>;
}
// O HTML do primeiro paint contém apenas <div>Loading...</div>Comparação de velocidade do primeiro paint
# SSR
FCP: 0.4s LCP: 0.8s TTI: 1.2s
SEO: crawlers recebem o conteúdo completo diretamente
# CSR
FCP: 0.6s LCP: 1.8s TTI: 2.4s
SEO: crawlers precisam executar JS para obter o conteúdoPerguntas frequentes
O que esta página de demonstração realmente está demonstrando?
É uma rota de referência de renderização no servidor (SSR) que mostra como uma página do Next.js App Router pode buscar dados no servidor, embutir o resultado na primeira resposta HTML e ainda assim carregar os textos localizados corretos. Não é uma utilidade para usuário final — é um teste de fumaça para desenvolvedores.
Os dados são buscados no servidor ou no navegador?
No servidor. A página chama serverApiFetch (com os cabeçalhos de requisição assinada de src/lib/sign.ts) dentro do React Server Component, então o navegador recebe uma página HTML que já contém os dados. Não há fetch no cliente no primeiro carregamento.
Por que a página às vezes mostra dados desatualizados?
O Next.js pode armazenar a resposta SSR em cache dependendo das configurações de revalidate. Se você precisa de dados atualizados a cada requisição, defina 'export const dynamic = "force-dynamic"' ou passe {cache: 'no-store'} para o fetch. A rota de demonstração usa o comportamento padrão para manter o exemplo simples.
Posso copiar esse padrão para minha própria página?
Sim — essa é a ideia. A rota mostra como combinar getTranslations do next-intl com um fetch no servidor e passar o resultado para um Client Component para interatividade. Copie o layout.tsx e o page.tsx e substitua a fonte de dados.
Por que preciso assinar as requisições para uma API interna?
X-Timestamp / X-Nonce / X-Sign bloqueiam ataques de replay e garantem que requisições vindas da web pública realmente partem de um cliente confiável. A chave de assinatura é por sessão para usuários logados e um valor padrão caso contrário; veja src/lib/sign.ts e src/lib/fetch.ts para a implementação.
Esta página existe em builds de produção?
Faz parte do app implantado para referência, mas não é linkada na home nem na lista de ferramentas, e não é divulgada como uma ferramenta para o usuário. Trate como documentação de desenvolvedor renderizada como rota.
O que devo olhar para entender a estrutura do projeto?
Comece pelo layout.tsx e page.tsx desta página, depois leia src/i18n.ts (configuração de locale), src/i18n/request.ts (carregamento global de traduções), src/lib/load-page-messages.ts (traduções por página) e src/lib/fetch.ts (wrappers de requisição assinada).