Anixt
Next.js

Checklist de SEO Técnico para Sites em Next.js (App Router)

Checklist verificável de SEO técnico para Next.js com App Router: renderização, metadata, canonical, sitemap, robots, Schema.org e Core Web Vitals.

· 10 min de leitura

Next.js resolve boa parte do SEO técnico por padrão, e é por isso que tantos sites em Next.js chegam à auditoria com os mesmos cinco problemas: canonical apontando para o preview da Vercel, sitemap sem as páginas dinâmicas, metadata duplicada entre layout e page, JSON-LD que não bate com o texto visível e imagem de herói sem prioridade. O framework dá as ferramentas, mas não configura o site por você.

Este checklist é o que aplicamos em todo projeto Next.js que entregamos, incluindo este site. Cada item tem o que verificar, como verificar e a API do framework envolvida. Ele assume App Router e Next.js 15 ou 16, e as APIs foram conferidas na documentação oficial do generateMetadata e do sitemap em setembro de 2026. Se você usa Pages Router, os conceitos valem, mas as APIs são outras.

1. Renderização: o HTML precisa chegar pronto

O Googlebot executa JavaScript, mas com fila e atraso. Crawlers de IA (GPTBot, ClaudeBot, PerplexityBot) executam pouco ou nada. A regra é simples: o conteúdo que importa para SEO precisa estar no HTML da resposta inicial, não montado depois no navegador.

No App Router, Server Components entregam isso por padrão. O problema aparece quando o time marca "use client" no componente que contém o texto principal, ou quando o conteúdo depende de useEffect para buscar dados.

Como verificar:

curl -s https://seusite.com.br/pagina | grep -c "<h1"

Se retornar zero, o H1 não está no HTML servido. Faça o mesmo para o parágrafo de abertura e para os dados estruturados. Outra opção é desligar o JavaScript no navegador e recarregar: o que sumir não existe para crawler de IA.

Checklist:

  • H1, texto principal e FAQ estão em Server Components ou são passados como props para Client Components (o HTML ainda é gerado no servidor)
  • Nenhum conteúdo indexável depende de useEffect ou de fetch no cliente
  • Páginas de conteúdo usam geração estática (generateStaticParams) ou cache com revalidação, não dynamic = "force-dynamic" sem motivo
  • loading.tsx não substitui o conteúdo por skeleton no HTML inicial de páginas estáticas

2. Metadata: título, descrição e a armadilha do layout

A Metadata API substitui o next/head. O que quebra na prática é a herança: metadata definida no layout.tsx raiz vale para todas as páginas que não a sobrescrevem, e é assim que dezenas de páginas acabam com o mesmo título.

Checklist:

  • Toda página tem title e description próprios, via export const metadata (estático) ou generateMetadata (dinâmico)
  • O layout raiz define title.template (por exemplo "%s | Anixt") e title.default, e as páginas passam só o título específico
  • metadataBase está definido no layout raiz com a URL de produção, para que caminhos relativos em canonical e openGraph.images resolvam corretamente
  • Títulos têm até cerca de 60 caracteres e descrições até cerca de 155, para não serem cortados na busca
  • openGraph e twitter estão preenchidos, com imagem gerada por opengraph-image.tsx quando a página é dinâmica

Exemplo mínimo de página dinâmica:

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params
  const post = getPostBySlug(slug)
  if (!post) return {}
  return {
    title: post.seoTitle ?? post.title,
    description: post.description,
    alternates: { canonical: `/blog/${slug}` },
  }
}

Note o await params: a partir do Next.js 15, params é uma Promise. Código migrado de versões anteriores que acessa params.slug direto compila com aviso e pode gerar metadata vazia.

3. Canonical: uma URL por conteúdo

Canonical errado é o defeito mais frequente em site Next.js hospedado na Vercel. Sem metadataBase, ou com ele lendo VERCEL_URL, o canonical de produção aponta para projeto-abc123.vercel.app, e o Google passa a tratar o domínio de preview como original.

Checklist:

  • metadataBase usa o domínio de produção fixo, não process.env.VERCEL_URL
  • Toda página indexável declara alternates.canonical com caminho relativo
  • Páginas com parâmetros de consulta (filtros, UTM, paginação) apontam o canonical para a versão limpa
  • Deploys de preview têm X-Robots-Tag: noindex ou usam a proteção de deploy da Vercel, para que nunca sejam indexados
  • www e não-www redirecionam para uma única versão com 308 (configure em next.config ou no provedor de DNS)
  • Barra final é consistente (trailingSlash no next.config), sem duas URLs servindo o mesmo conteúdo

Como verificar: abra o HTML de produção e confira o <link rel="canonical">. Depois, no Search Console, use a inspeção de URL e compare "URL canônica declarada pelo usuário" com "URL canônica selecionada pelo Google". Se divergem, o Google não aceitou a sua.

4. Sitemap e robots como código

No App Router, app/sitemap.ts e app/robots.ts geram os arquivos em build. A vantagem é que o sitemap pode ler a mesma fonte de dados das páginas. O erro comum é o sitemap listar só as rotas estáticas e esquecer as dinâmicas (posts, cidades, serviços).

Checklist:

  • sitemap.ts inclui todas as páginas indexáveis, incluindo as geradas por generateStaticParams
  • lastModified reflete a data real de alteração do conteúdo, não new Date() em toda build (isso faz o Google ignorar o campo)
  • Sites com mais de 50 mil URLs usam generateSitemaps para dividir em múltiplos arquivos
  • robots.ts aponta para o sitemap e bloqueia apenas o que não deve ser indexado (/api/, /obrigado/, áreas logadas)
  • robots.ts não bloqueia crawlers de IA por engano; veja a lista de user-agents em como aparecer no ChatGPT, Gemini e Perplexity
  • Páginas que não devem indexar (obrigado, busca interna, rascunho) usam robots: { index: false } na metadata, não só o robots.txt

Exemplo de sitemap com páginas dinâmicas:

import type { MetadataRoute } from "next"

export default function sitemap(): MetadataRoute.Sitemap {
  const posts = getAllPosts().map((post) => ({
    url: `https://seusite.com.br/blog/${post.slug}`,
    lastModified: post.updatedAt ?? post.publishedAt,
    changeFrequency: "monthly" as const,
  }))
  return [{ url: "https://seusite.com.br", lastModified: "2026-09-01" }, ...posts]
}

5. Dados estruturados: JSON-LD que bate com a página

O Google é claro no seu guia sobre recursos de IA: os dados estruturados precisam corresponder ao texto visível. Schema de FAQ com perguntas que não aparecem na página, ou LocalBusiness com telefone diferente do rodapé, é ignorado ou penalizado.

No Next.js, JSON-LD entra como <script type="application/ld+json"> renderizado no servidor, dentro do componente da página. Não use next/script com estratégia afterInteractive para isso, porque o script só entra no DOM depois da hidratação.

Checklist:

  • Organization (ou LocalBusiness) com @id estável no layout raiz, referenciado pelas outras entidades
  • WebSite com @id e publisher apontando para a organização
  • BreadcrumbList em toda página abaixo da home, coerente com a navegação visível
  • Article ou BlogPosting em posts, com author do tipo Person, datePublished e dateModified reais
  • Service em páginas de serviço, FAQPage só onde a FAQ está visível no HTML
  • Tipos específicos quando existem: AutoRepair, MedicalBusiness, LegalService, Dentist
  • Dados sensíveis (telefone, endereço, horário) vêm da mesma constante usada no rodapé, para não divergirem
  • Validado no teste de pesquisa aprimorada do Google e no validador do Schema.org

6. Core Web Vitals: os limites e onde o Next.js falha

Os limites oficiais, segundo a documentação do Google Search Central, continuam os mesmos em 2026: LCP até 2,5 s, INP até 200 ms, CLS até 0,1, medidos no percentil 75 de usuários reais. Artigos que citam LCP de 2,0 s ou INP de 150 ms não apontam fonte do Google.

Next.js entrega bons números por padrão, e os problemas costumam vir de decisões do projeto:

MétricaCausa comum em Next.jsCorreção
LCP altoImagem de herói sem priority, fonte externa bloqueando render, componente de herói em Client Component pesadopriority no next/image do herói, next/font com display: swap, herói em Server Component
CLS altonext/image sem width/height ou fill sem container dimensionado, banner de cookies inserido depois do carregamento, fonte trocando de tamanhoDimensões explícitas, espaço reservado para elementos tardios, size-adjust via next/font
INP altoHidratação de árvore grande de Client Components, biblioteca de animação rodando na thread principal, handlers pesados em scrollReduzir "use client" ao mínimo, dynamic() com ssr: false para widgets não críticos, requestIdleCallback para trabalho não urgente

Checklist:

  • Imagem de herói usa next/image com priority e sizes correto
  • Fontes carregam por next/font (self-hosted, sem requisição externa em tempo de render)
  • Nenhum script de terceiros (chat, analytics, pixel) carrega com beforeInteractive sem necessidade
  • Bundle de cliente da página inicial abaixo de 200 kB comprimido (verifique com @next/bundle-analyzer)
  • Dados de campo no Search Console (relatório Core Web Vitals) e no PageSpeed Insights estão verdes, não só o Lighthouse local

7. Estrutura, links internos e o resto que o crawler lê

  • Um único <h1> por página, e ele é o título do conteúdo, não o logo
  • Hierarquia h2 e h3 sem pular níveis
  • Links internos usam next/link com href real (não onClick com router.push), para que apareçam no HTML
  • Toda página indexável recebe ao menos um link interno de outra página; páginas órfãs não ranqueiam
  • Breadcrumb visível e coerente com a URL
  • not-found.tsx retorna status 404 real (o App Router faz isso ao chamar notFound()), e páginas removidas redirecionam com 301 ou 308 via next.config ou middleware
  • Imagens de conteúdo têm alt descritivo; imagens decorativas têm alt=""
  • lang="pt-BR" no <html> do layout raiz

8. Verificação final antes do deploy

Um roteiro de dez minutos que pega a maioria dos problemas:

  1. curl da home e de uma página dinâmica: H1, canonical e JSON-LD presentes no HTML
  2. /sitemap.xml e /robots.txt abrindo em produção, com as URLs de produção
  3. Inspeção de URL no Search Console para uma página nova, confirmando indexação permitida e canonical aceito
  4. PageSpeed Insights em mobile para home e página de serviço mais importante
  5. Teste de pesquisa aprimorada para uma página com FAQ e uma com Article
  6. Busca site:seudominio.com.br no Google para conferir se URLs de preview ou parâmetros estranhos foram indexados

Perguntas frequentes

Next.js é melhor para SEO do que WordPress?

Não por si só. Next.js dá controle total sobre HTML, performance e dados estruturados, o que permite chegar a um resultado técnico melhor. Mas exige que alguém implemente cada item deste checklist. WordPress com tema leve e plugin de SEO configurado chega a um resultado aceitável com menos trabalho. A diferença aparece em escala, performance e em projetos com páginas programáticas, como as Paginações SEO.

Preciso de generateStaticParams em todas as rotas dinâmicas?

Para rotas de conteúdo que você quer indexadas, sim, ou ao menos de cache com revalidação. Páginas geradas sob demanda sem cache respondem mais devagar ao crawler e consomem orçamento de rastreamento. Rotas que dependem de usuário logado não precisam, porque não devem ser indexadas.

O App Router indexa pior que o Pages Router?

Não. O HTML gerado é equivalente ou melhor, porque Server Components enviam menos JavaScript. Os problemas atribuídos ao App Router quase sempre vêm de "use client" em excesso ou de metadata herdada do layout sem sobrescrita.

Como sei se crawlers de IA estão conseguindo ler o site?

Verifique nos logs do servidor ou do provedor as requisições com user-agent GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot e Google-Extended, e confira se retornam 200 com o HTML completo. Se o site está atrás de proteção contra bots, confira se esses agentes não estão sendo bloqueados na camada de rede, o que o robots.txt não mostra.

A Anixt aplica este checklist em todo projeto de desenvolvimento em Next.js e em auditorias de sites existentes. Se quer o resultado da verificação para o seu site, com o que passa e o que falha em cada item, é esse o ponto de partida.

AnixtEscrito e revisado por · Fundador e responsável técnico

Pronto para aplicar isso no seu negócio?

Solicite um diagnóstico gratuito e descubra o caminho certo para sua presença digital.

  • Resposta em até 24h
  • Orçamento gratuito
  • Domínio e acessos no seu nome
WhatsApp