Next.js の SEO:ChatGPT に御社のサイトを引用してもらうには?

どのページも、JavaScript がなくても読めるようにし、内容を明確に記述し、ChatGPT の検索クローラーを通してください。Next.js では、本文が HTML に含まれるサーバーコンポーネント、タイトル、正規 URL、言語を設定するメタデータ API、OAI-SearchBot を許可する app/robots.ts、app/sitemap.ts、そしてページ内の JSON-LD を使います。これで引用が保証されるわけではありません。ChatGPT がページを使えない理由を取り除くだけです。

ファクト

  • OpenAI によると、OAI-SearchBot をブロックしたサイトは、ChatGPT の検索回答には表示されません。robots.txt の変更が反映されるまで、およそ 24 時間かかることがあります。 (OpenAI: Overview of OpenAI crawlers)
  • OpenAI によると、GPTBot をブロックすることは、そのコンテンツをモデルの学習に使わないという意思表示にすぎません。ChatGPT-User によるアクセスはユーザーが開始するもので、検索に何が表示されるかを決めるためには使われません。 (OpenAI: Overview of OpenAI crawlers)
  • Next.js によると、v13.2.0 以降で使える metadata のエクスポートと generateMetadata は、サーバーコンポーネントでのみ動作するため、メタデータを最初の HTML に含められます。 (Next.js ドキュメント: generateMetadata)
  • Next.js は v13.3.0 以降、app/robots.ts から robots.txt を生成します。ユーザーエージェントごとにルールを指定できます。 (Next.js ドキュメント: robots.txt)
  • app/sitemap.ts は、Next.js v14.2.0 以降、言語ごとの代替 URL に対応しています。Google のサイトマップの上限は、サイトマップ一つにつき 50,000 URL です。 (Next.js ドキュメント: sitemap.xml)

許可する必要がある OpenAI のクローラーはどれですか?

ChatGPT の検索に御社のサイトを表示できるかどうかを決めるのは OAI-SearchBot です。三つのクローラーはそれぞれ役割が異なるため、ブロックするか許可するかは個別に決めてください。

// app/robots.ts

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",
  };
}
ユーザーエージェント役割ブロックした場合の影響
OAI-SearchBotChatGPT の検索機能のためにサイトをクロールする御社のページは ChatGPT の検索回答に表示されない
GPTBotOpenAI のモデル学習に使われる可能性のあるコンテンツをクロールするコンテンツは学習に使われなくなる。検索には影響しない
ChatGPT-Userユーザーの質問でそのページが必要になったときに訪問するrobots.txt が適用されないことがある。検索は決めない

なぜ本文はサーバー側で描画される必要があるのですか?

ChatGPT のクローラーは、サーバーが送る HTML を読み、JavaScript は実行しないためです。App Router では、ページはデフォルトでサーバーコンポーネントです。読み込み後にクライアントコンポーネントで取得した本文は、その HTML に含まれません。ページはサーバーコンポーネントのままにし、インタラクティブな部分だけを "use client" のファイルに移してください。

各ページのメタデータには何を含めればよいですか?

一意のタイトルと説明文、正規 URL、そして多言語のサイトでは言語の代替 URL です。generateMetadata でページごとに作成します。Next.js は代替 URL を rel="canonical" と hreflang のリンクに変換します。JSON-LD は、Next.js のドキュメントが示すとおり、「<」をエスケープした通常の script タグとしてページに入れ、表示されている本文と同じ内容にしてください。

// app/guides/[slug]/page.tsx (a Server Component: no "use client")

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

クローラーのように確認するにはどうすればよいですか?

ブラウザを使わずに公開中のページを取得し、回答の本文、タイトル、正規 URL、JSON-LD があるかを確認します。本文が生の HTML に含まれていなければ、ChatGPT はそれを引用できません。

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

完璧な設定をすれば、引用されますか?

いいえ。設定によって、ページは読めて対象になるようになります。ただし ChatGPT は、ページがどれだけ質問によく答えているかで情報源を選びます。内容は、お客様が尋ねることへの最も明確な答えでなければなりません。

ステップごとの手順

  1. robots を確認する. OAI-SearchBot を許可し、サイトマップを指す app/robots.ts を追加します。GPTBot は別途決めてください。
  2. ページをサーバー側に置く. 公開されているすべてのページがサーバーコンポーネントで、主な本文が HTML に含まれていることを確認します。
  3. メタデータを追加する. generateMetadata を使い、すべてのページに一意のタイトル、説明文、正規 URL、言語の代替 URL を設定します。
  4. JSON-LD とサイトマップを追加する. ページに JSON-LD を描画し、公開されているすべての URL を app/sitemap.ts に載せます。
  5. 公開中のサイトを確認する. localhost ではなく、デプロイの後に curl による確認を実行します。

よくある間違い

  • 学習だけをブロックするつもりなのに、一つのルールで GPTBot と OAI-SearchBot をまとめてブロックすること。
  • 記事の本文を useEffect で読み込み、クローラーが受け取る HTML が空になること。
  • ルートのレイアウトから、同じタイトル、説明文、正規 URL をすべてのページにコピーすること。
  • 表示されているページが述べていないことを主張する JSON-LD を書くこと。

easyIndex での解決方法

easyIndex は、作業がお使いのリポジトリ内に留まるため、Next.js のサイトに向いています。御社のコーディングエージェントがページを書き、easyIndex が MCP 経由でステップを渡します。提出されたページを監査し、公開中のサイトで確認するため、ステップはエージェントの報告ではなく、easyIndex が確認した証拠によってのみ完了します。

その後、ダッシュボードには、ページごとの AI アシスタントからの訪問と、AI クローラーが読んだページが表示されます。すべての機能を含むプランは、1サイトあたり月額 US$30 で、1サイトで利用できる7日間の無料トライアル付きです。

よくある質問

GPTBot をブロックすべきですか?

御社が決めることです。OpenAI によると、GPTBot は学習用、OAI-SearchBot は検索用です。そのため、GPTBot だけをブロックしても、ChatGPT の検索から外れることはありません。

Pages Router と App Router のどちらが必要ですか?

どちらでもサーバー側で描画された HTML を送れます。このガイドは App Router を使っています。App Router では、ページはデフォルトでサーバーコンポーネントであり、メタデータ API もそこにあります。

llms.txt は必要ですか?

必要ありません。ChatGPT の検索はページを読みます。llms.txt ファイルが、HTML の本文の代わりになるわけではありません。

robots.txt の変更が反映されるまで、どのくらいかかりますか?

OpenAI によると、robots.txt を更新した後、検索システムが調整するまでおよそ 24 時間かかります。

続きを読む

最終確認日 .

Next.js の SEO:ChatGPT に引用されるための設定