SEO no Next.js: como fazer meu site ser citado pelo ChatGPT?

Deixe cada página legível sem JavaScript, descreva a página e libere o robô de busca do ChatGPT. No Next.js isso é: Server Components com o texto no HTML, Metadata API para título, canonical e idiomas, app/robots.ts liberando o OAI-SearchBot, app/sitemap.ts e JSON-LD na página. Nada disso garante citação; só tira os motivos para o ChatGPT não usar sua página.

Fatos

  • A OpenAI diz que sites que bloqueiam o OAI-SearchBot não aparecem nas respostas da busca do ChatGPT, e que uma mudança no robots.txt leva cerca de 24 horas para valer. (OpenAI: Overview of OpenAI crawlers)
  • A OpenAI diz que bloquear o GPTBot só indica que o conteúdo não deve treinar os modelos; as visitas do ChatGPT-User partem do usuário e não decidem o que aparece na busca. (OpenAI: Overview of OpenAI crawlers)
  • O Next.js diz que o export metadata e o generateMetadata, existentes desde a v13.2.0, só funcionam em Server Components, para a metadata sair no HTML inicial. (Next.js docs: generateMetadata)
  • O Next.js gera o robots.txt a partir do app/robots.ts desde a v13.3.0, com regras por user agent. (Next.js docs: robots.txt)
  • O app/sitemap.ts aceita URLs alternativas por idioma desde a v14.2.0 do Next.js, e o limite do Google é de 50.000 URLs por sitemap. (Next.js docs: sitemap.xml)

Qual robô da OpenAI eu preciso liberar?

O OAI-SearchBot é o que decide se a busca do ChatGPT pode mostrar seu site. Os três têm funções diferentes, então libere ou bloqueie cada um separado.

// app/robots.ts
import type { MetadataRoute } from "next";

export default function robots(): MetadataRoute.Robots {
  return {
    rules: [
      { userAgent: "*", allow: "/" },
      // ChatGPT search: must be allowed to be shown in answers
      { userAgent: "OAI-SearchBot", allow: "/" },
      // Model training: your choice, it does not decide search
      { userAgent: "GPTBot", allow: "/" },
    ],
    sitemap: "https://www.example.com/sitemap.xml",
  };
}
User agentO que fazEfeito de bloquear
OAI-SearchBotRastreia sites para a busca do ChatGPTSuas páginas não aparecem nas respostas da busca do ChatGPT
GPTBotRastreia conteúdo que pode treinar os modelos da OpenAIO conteúdo não vai para treino; a busca não muda
ChatGPT-UserVisita a página quando a pergunta de um usuário pedeO robots.txt pode não valer; não decide a busca

Por que o texto precisa vir renderizado do servidor?

Porque os robôs do ChatGPT leem o HTML que o servidor envia e não executam JavaScript. No App Router as páginas são Server Components por padrão; texto buscado num Client Component depois de carregar não está nesse HTML. Mantenha a página como Server Component e leve só as partes interativas para arquivos com "use client".

O que a metadata de cada página precisa ter?

Título e descrição únicos, URL canônica e, em site multilíngue, as alternativas de idioma. O generateMetadata monta isso por página; o Next.js transforma alternates em links rel="canonical" e hreflang. O JSON-LD entra na página numa tag script simples, com "<" escapado como a documentação do Next.js mostra, e precisa dizer o mesmo que o texto visível.

// app/guides/[slug]/page.tsx (a Server Component: no "use client")
import type { Metadata } from "next";

export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
  const { slug } = await params;
  const page = await getPage(slug);
  return {
    title: page.title,
    description: page.description,
    alternates: {
      canonical: `/guides/${slug}`,
      languages: { "pt-BR": `/pt/guides/${slug}`, es: `/es/guides/${slug}` },
    },
  };
}

export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const page = await getPage(slug);
  const jsonLd = { "@context": "https://schema.org", "@type": "Article", headline: page.title };
  return (
    <article>
      <script type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd).replace(/</g, "\\u003c") }} />
      <h1>{page.title}</h1>
      <p>{page.answer}</p>
    </article>
  );
}

Como testo do jeito que o robô vê?

Baixe a página em produção sem navegador e procure o texto da resposta, o título, o canonical e o JSON-LD. Se o texto não está no HTML bruto, o ChatGPT não consegue citar.

# 1. The text is in the raw HTML (no JavaScript run)
curl -s -A "OAI-SearchBot" https://www.example.com/guides/my-page | grep -i "a sentence from the answer"

# 2. Title, canonical and JSON-LD are there too
curl -s https://www.example.com/guides/my-page | grep -iE "<title>|rel=\"canonical\"|ld\+json"

# 3. robots.txt and sitemap answer
curl -s https://www.example.com/robots.txt
curl -s https://www.example.com/sitemap.xml | grep -c "<loc>"

Com tudo certo eu vou ser citado?

Não necessariamente. A configuração deixa as páginas legíveis e elegíveis; o ChatGPT escolhe fontes pela qualidade da resposta. O conteúdo ainda precisa ser a resposta mais clara para o que seus clientes perguntam.

Passo a passo

  1. Confira o robots. Crie o app/robots.ts liberando o OAI-SearchBot e apontando o sitemap; decida o GPTBot à parte.
  2. Mantenha as páginas no servidor. Garanta que toda página pública é Server Component com o texto principal no HTML.
  3. Adicione a metadata. Use generateMetadata para título, descrição, canonical e idiomas únicos em cada página.
  4. Adicione JSON-LD e sitemap. Renderize o JSON-LD na página e liste toda URL pública no app/sitemap.ts.
  5. Teste em produção. Rode os testes com curl depois do deploy, não no localhost.

Erros comuns

  • Bloquear GPTBot e OAI-SearchBot juntos numa regra só, quando a ideia era bloquear só o treino.
  • Carregar o texto do artigo em useEffect, deixando vazio o HTML que o robô recebe.
  • Repetir o mesmo título, descrição ou canonical em todas as páginas a partir do layout raiz.
  • JSON-LD dizendo coisas que a página visível não diz.

Como o easyIndex resolve

O easyIndex combina com um site em Next.js porque o trabalho fica no seu repositório: seu agente de código escreve as páginas e o easyIndex dá os passos via MCP, audita cada página no envio e confere no site no ar, então um passo só fecha com evidência que ele mesmo checa, não com o relato do agente.

Depois o painel mostra visitantes vindos de assistentes de IA por página e quais páginas os robôs de IA leram. Um plano com tudo: R$ 57 por site por mês, 7 dias grátis com um site.

Perguntas frequentes

Devo bloquear o GPTBot?

A escolha é sua. A OpenAI diz que o GPTBot é para treino e o OAI-SearchBot para busca, então bloquear só o GPTBot não tira você da busca do ChatGPT.

Preciso do Pages Router ou do App Router?

Os dois conseguem enviar HTML renderizado no servidor. Este guia usa o App Router, onde as páginas são Server Components por padrão e fica a Metadata API.

O llms.txt é obrigatório?

Não. A busca do ChatGPT lê suas páginas; um llms.txt não substitui o texto no HTML.

Quanto tempo leva para uma mudança no robots.txt valer?

A OpenAI fala em cerca de 24 horas para os sistemas de busca dela se ajustarem.

Continue lendo

Verificado em .

SEO no Next.js: como ser citado pelo ChatGPT