Executando verificação de segurança...
6

Next.js 15: “55 milhões de páginas” sem SSG, SSR sob demanda e SEO

No CNPJ Aberto eu tenho a rota /cnpj/[cnpj] com title, description, OG image e JSON-LD por empresa. Pra mim não dava pra pré-gerar tudo no build: seriam dias e armazenamento absurdo.

A saída que eu escolhi foi App Router + Server Components: HTML no servidor na hora do request, metadados com generateMetadata, sem promessa de SSG pra cada CNPJ.

Server Component na página

Minha page.tsx da ficha não é "use client". O que ganhei:

  • HTML útil no primeiro byte pra crawler
  • generateMetadata alinhado com o mesmo dado da página
  • Menos JS obrigatório no primeiro carregamento

O padrão que ajudou: cache() do React em volta do fetch da empresa — generateMetadata e o corpo da página compartilham a mesma chamada e eu evito query duplicada.

OG image dinâmica

Usei opengraph-image.tsx com ImageResponse (next/og): gero imagem sob demanda com nome da empresa, CNPJ, situação, etc. Quando alguém compartilha o link, eu quero preview real, não um card genérico.

JS só onde precisa

A ficha tem coisas pesadas (grafo, mapa, ações Pro…). Eu usei next/dynamic e lazy() onde o interativo não é above-the-fold — chunk separado, carrega quando faz sentido. Eu vi menos JS inicial e LCP mais previsível.

URL canônica

Eu sei que CNPJ aparece formatado de mil jeitos na URL. Por isso eu coloquei middleware que redireciona 301 pra forma “só dígitos” quando detecta 14 dígitos com lixo de pontuação — eu quis evitar diluir sinal de SEO em duplicata.

JSON-LD

Eu injeto Organization com endereço, taxID, etc., como <script type="application/ld+json">. Eu não trato isso como mágica de ranking, mas deixa explícita a intenção da página pra quem consome structured data.

API no mesmo host

Eu configurei rewrite no next.config: o browser chama /api/... e o Next encaminha pro backend. Eu reduzi dor de CORS no cliente; no SSR eu falo com URL interna direto no backend.

Métricas (referência)

PageSpeed / campo real variam, mas a direção que eu vi foi: LCP na casa de ~1 s, CLS baixo, bundle inicial da ficha na casa de dezenas de KB gzip depois do split — não centenas.


Pra “infinitas” URLs dinâmicas, SSR + metadados server-side + dynamic import foi o que mais fez sentido pro site, em vez de fingir que dá pra estátizar o Brasil inteiro no next build.

Carregando publicação patrocinada...
1

po, Que massa!

eu tenho uma estrutura parecida no meu site tambem (ByDoctor) que é para comparacao com os concorrentes /vs/ mas como nao sao muuuuitos (igual cnpj) eu nem precisei me preocupar com o tamanho

mas muito legal pensar no "problema" que voce teve

valeuu por compartilhar

1

Nextjs, apesar das várias polêmicas... quando se trata se server components com SEO ele resolve. Agora como que é o seu banco de dados e cloud? Seria massa um post sobre isso, fica a sugestão. Vlw

1
1

Eu sei que CNPJ aparece formatado de mil jeitos na URL. Por isso eu coloquei middleware que redireciona 301 pra forma “só dígitos” quando detecta 14 dígitos com lixo de pontuação — eu quis evitar diluir sinal de SEO em duplicata.
Fonte: URL Canônica

A aplicação ja está preparada proo novo formato de CNPJ, que inclui letras também?

1

Então, desccobri isso ontem um pouco antes de fazer esse post. Não está e preciso adaptar. Inclusive é um breaking change no meu banco de dados.

1

Uma breaking change no db? Geralmente o cnpj no banco é representada por text ou varchar, você usou algo diferente? Eu precisei migrar um sistema menor e foi apenas regras de validação que teve que trocar pra aceitar alfanumérico e calcular corretamente o verificador.