SEO con Next.js: come faccio a farmi citare da ChatGPT?

Rendi ogni pagina leggibile senza JavaScript, descrivila e lascia entrare il crawler di ricerca di ChatGPT. In Next.js questo significa Server Components con il testo nell'HTML, la Metadata API per titolo, canonical e lingue, app/robots.ts che consente OAI-SearchBot, app/sitemap.ts, e JSON-LD nella pagina. Niente di tutto questo garantisce una citazione; elimina però i motivi per cui ChatGPT non può usare la tua pagina.

Dati

  • OpenAI dice che i siti che escludono OAI-SearchBot non vengono mostrati nelle risposte della ricerca di ChatGPT, e una modifica a robots.txt può richiedere circa 24 ore per avere effetto. (OpenAI: Overview of OpenAI crawlers)
  • OpenAI dice che bloccare GPTBot segnala solo che i contenuti non devono servire ad addestrare i suoi modelli; le visite di ChatGPT-User sono avviate dagli utenti e non servono a decidere cosa compare nella ricerca. (OpenAI: Overview of OpenAI crawlers)
  • Next.js dice che l'esportazione metadata e generateMetadata, disponibili dalla versione 13.2.0, funzionano solo nei Server Components, così i metadati possono stare nell'HTML iniziale. (Documentazione di Next.js: generateMetadata)
  • Next.js genera robots.txt da app/robots.ts dalla versione 13.3.0, con regole per ogni user agent. (Documentazione di Next.js: robots.txt)
  • app/sitemap.ts supporta gli URL alternativi per lingua dalla versione 14.2.0 di Next.js, e il limite di Google è di 50.000 URL per sitemap. (Documentazione di Next.js: sitemap.xml)

Quale crawler di OpenAI devo consentire?

OAI-SearchBot è quello che decide se la ricerca di ChatGPT può mostrare il tuo sito. I tre hanno compiti diversi, quindi bloccali o consentili separatamente.

// 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 agentCosa faEffetto del blocco
OAI-SearchBotScansiona i siti per le funzioni di ricerca di ChatGPTLe tue pagine non vengono mostrate nelle risposte della ricerca di ChatGPT
GPTBotScansiona contenuti che possono servire ad addestrare i modelli di OpenAII contenuti non servono all'addestramento; la ricerca non cambia
ChatGPT-UserVisita una pagina quando la domanda di un utente ne ha bisognorobots.txt potrebbe non applicarsi; non decide la ricerca

Perché il testo deve essere generato sul server?

Perché i crawler di ChatGPT leggono l'HTML che il tuo server invia e non eseguono JavaScript. Nell'App Router le pagine sono Server Components per impostazione predefinita; il testo recuperato in un Client Component dopo il caricamento manca in quell'HTML. Mantieni la pagina come Server Component e sposta nei file "use client" solo le parti interattive.

Cosa devono includere i metadati di ogni pagina?

Un titolo e una descrizione unici, un URL canonical e, nei siti multilingua, le alternative per lingua. generateMetadata le costruisce per ogni pagina; Next.js trasforma le alternative in link rel="canonical" e hreflang. Il JSON-LD va nella pagina come semplice tag script, con "<" sostituito come mostra la documentazione di Next.js, e deve dire le stesse cose del testo visibile.

// 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>
  );
}

Come lo testo come farebbe un crawler?

Scarica la pagina online senza browser e cerca il testo della risposta, il titolo, il canonical e il JSON-LD. Se il testo non è nell'HTML grezzo, ChatGPT non può citarlo.

# 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>"

Con una configurazione perfetta vengo citato?

No. La configurazione rende le pagine leggibili e idonee; ChatGPT sceglie le fonti in base a quanto bene una pagina risponde alla domanda. Il contenuto deve comunque essere la risposta più chiara a ciò che chiedono i tuoi acquirenti.

Passo dopo passo

  1. Controlla robots. Aggiungi app/robots.ts che consente OAI-SearchBot e punta alla sitemap; decidi separatamente su GPTBot.
  2. Tieni le pagine sul server. Verifica che ogni pagina pubblica sia un Server Component con il testo principale nell'HTML.
  3. Aggiungi i metadati. Usa generateMetadata per un titolo, una descrizione, un canonical e le alternative di lingua unici su ogni pagina.
  4. Aggiungi JSON-LD e la sitemap. Genera il JSON-LD nella pagina ed elenca ogni URL pubblico in app/sitemap.ts.
  5. Testa il sito online. Esegui i controlli con curl dopo il deploy, non in localhost.

Errori comuni

  • Bloccare GPTBot e OAI-SearchBot con un'unica regola quando si voleva bloccare solo l'addestramento.
  • Caricare il testo dell'articolo in useEffect, così l'HTML che riceve il crawler è vuoto.
  • Copiare lo stesso titolo, la stessa descrizione o lo stesso canonical su ogni pagina dal layout radice.
  • JSON-LD che afferma cose che la pagina visibile non dice.

Come lo risolve easyIndex

easyIndex si adatta bene a un sito Next.js perché il lavoro resta nel tuo repository: il tuo agente di codifica scrive le pagine e easyIndex fornisce i passi via MCP, controlla ogni pagina quando viene inviata e la verifica sul sito online, così un passo si completa con le prove che verifica, non con il report dell'agente.

Poi la dashboard mostra i visitatori degli assistenti AI per pagina e quali pagine leggono i crawler AI. Un solo piano con tutte le funzioni: US$ 30 al mese per sito, prova gratuita di 7 giorni con un sito.

Domande frequenti

Devo bloccare GPTBot?

È una tua scelta. OpenAI dice che GPTBot serve per l'addestramento e OAI-SearchBot per la ricerca, quindi bloccare solo GPTBot non ti esclude dalla ricerca di ChatGPT.

Mi serve il Pages Router o l'App Router?

Entrambi possono inviare HTML generato sul server. Questa guida usa l'App Router, dove le pagine sono Server Components per impostazione predefinita e vive la Metadata API.

Serve llms.txt?

No. La ricerca di ChatGPT legge le tue pagine; un file llms.txt non sostituisce il testo nell'HTML.

Quanto tempo passa prima che una modifica a robots.txt conti?

OpenAI dice circa 24 ore perché i suoi sistemi di ricerca si adeguino dopo un aggiornamento di robots.txt.

Continua a leggere

Verificato il .

SEO con Next.js: come farsi citare da ChatGPT