AI検索が普及するにつれ、「Webサイトの技術スタックがAIからの引用率に影響する」という現実が見えてきました。 SSG(静的サイト生成)はAIクローラとの相性がよく、中でもAstroはコンテンツサイトに特化した設計を持っています。

この記事では、AstroでGEO対応サイトを構築する手順を、コード例付きで解説します。 マーケティング担当者が開発チームに依頼する際のチェックリストとしても使える構成です。

SSGがGEO対策に強い理由

SSGで生成されたページは、ビルド時にHTMLが確定しています。 AIクローラがアクセスした瞬間に、すべてのテキストがHTMLとして読める状態です。

多くのAIクローラはJavaScriptを実行しません(searchviu.com, 2025の調査より)。 SPAやCSRで構築されたサイトでは、クローラが空の<div id="root"></div>しか取得できません。

<!-- CSR: クローラが受け取るHTML -->
<html>
  <body>
    <div id="root"></div>
    <script src="/bundle.js"></script>
  </body>
</html>

<!-- SSG: クローラが受け取るHTML -->
<html>
  <body>
    <article>
      <h1>AI検索の仕組みと対策</h1>
      <p>RAGは検索と生成を組み合わせた手法です...</p>
    </article>
    <script type="application/ld+json">
      {"@context":"https://schema.org","@type":"Article",...}
    </script>
  </body>
</html>

AIクローラにとって、下のHTMLは即座に内容を理解できるものです。 上のHTMLからは何も得られません。

AstroがGEO対策に向いている設計上の理由

Astroの「アイランドアーキテクチャ」は、ページの大部分を静的HTMLとして出力し、インタラクティブな部分だけにJavaScriptを送ります。 結果として、AIクローラが受け取るHTMLにテキストコンテンツがそのまま含まれます。

特徴AstroNext.jsGatsby
デフォルトのレンダリングSSG(ゼロJS)SSRSSG
JSランタイム出力必要な部分のみ全ページ全ページ
コンテンツコレクション組み込みなし(自前実装)GraphQLプラグイン

GEO対策の観点では、ビルド時にMarkdownからHTMLへ変換されるため、クローラが確実に読めること。 フロントマターでメタデータを管理でき、構造化データの自動生成が容易なこと。 ゼロJSがデフォルトなので、不要なJSがクローラの解析を妨げないこと。 この3点がAstroの強みです。

コンテンツコレクションでメタデータを型安全に管理する

Astroのコンテンツコレクションは、Markdownファイルのフロントマターをスキーマで検証する仕組みです。 src/content/config.ts でスキーマを定義します。

import { defineCollection, z } from 'astro:content';

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string().max(70),
    description: z.string().max(160),
    category: z.string(),
    tags: z.array(z.string()),
    publishedAt: z.coerce.date(),
    updatedAt: z.coerce.date().optional(),
    author: z.object({
      name: z.string(),
      url: z.string().url().optional(),
    }).default({ name: '編集部' }),
    evidenceRefs: z.array(z.string()).optional(),
    draft: z.boolean().default(false),
  }),
});

export const collections = { blog };

このスキーマにより、titleが70文字以内、descriptionが160文字以内、publishedAtが必須であることが保証されます。 フロントマターに不足があればビルド時にエラーになるため、公開前にメタデータの漏れを防げます。

構造化データ(JSON-LD)の自動生成

構造化データは、AIがコンテンツのメタ情報を機械的に読み取るための仕組みです。 src/components/StructuredData.astro を作成します。

---
interface Props {
  title: string;
  description: string;
  publishedAt: Date;
  updatedAt?: Date;
  author: { name: string; url?: string };
  url: string;
}

const { title, description, publishedAt, updatedAt, author, url } = Astro.props;

const jsonLd = {
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": title,
  "description": description,
  "datePublished": publishedAt.toISOString(),
  ...(updatedAt && { "dateModified": updatedAt.toISOString() }),
  "author": {
    "@type": "Person",
    "name": author.name,
    ...(author.url && { "url": author.url }),
  },
  "publisher": {
    "@type": "Organization",
    "name": "自社名",
    "url": "https://example.com",
  },
  "mainEntityOfPage": { "@type": "WebPage", "@id": url },
};
---

<script type="application/ld+json" set:html={JSON.stringify(jsonLd)} />

このコンポーネントを記事テンプレートの<head>内で呼び出せば、ビルド後のHTMLにJSON-LDが埋め込まれます。 AIクローラはこのJSON-LDを解析し、記事の著者・公開日・トピックを正確に把握します。

サイトマップ・RSS・robots.txtの設定

AIクローラがサイト全体の構造を効率的に把握できるよう、3つの設定を行います。

npx astro add sitemap
npm install @astrojs/rss
// astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com',
  integrations: [
    sitemap({
      filter: (page) => !page.includes('/draft/'),
    }),
  ],
});

public/robots.txt でAIクローラを明示的に許可します。

User-agent: *
Allow: /

User-agent: GPTBot
Allow: /

User-agent: PerplexityBot
Allow: /

User-agent: ClaudeBot
Allow: /

Sitemap: https://example.com/sitemap-index.xml

デフォルトのDisallow設定がAIクローラをブロックしているケースは多いです。 開発チームに確認し、明示的にAllowを設定してください。

動的ルーティングとタグページの生成

コンテンツコレクションから記事ページを自動生成します。

---
// src/pages/blog/[...slug].astro
import { getCollection } from 'astro:content';
import BlogPost from '../../layouts/BlogPost.astro';

export async function getStaticPaths() {
  const posts = await getCollection('blog', ({ data }) => !data.draft);
  return posts.map((entry) => ({
    params: { slug: entry.slug },
    props: { entry },
  }));
}

const { entry } = Astro.props;
const { Content } = await entry.render();
---

<BlogPost entry={entry}>
  <Content />
</BlogPost>

タグページも生成して、コンテンツ間の関係をAIクローラに明示します。

デプロイとクローラ検証

ビルド後、AIクローラがコンテンツを正しく読めているか検証します。

npm run build

# GPTBotとしてアクセスし、HTMLを取得
curl -A "GPTBot" https://example.com/blog/sample-article/ | head -50

curlの結果に記事のテキストが含まれていれば、AIクローラも同じ内容を取得できています。

まとめ——AstroとGEO対策の実践ポイント

AstroのSSGは、AIクローラにコンテンツを「確実に読ませる」ための技術基盤です。 ゼロJSデフォルト、コンテンツコレクション、構造化データの自動生成が、GEO対策の要件と合致しています。

開発チームがテンプレートとスキーマを整備すれば、マーケティング担当者はMarkdownを書くだけでGEO対応ページが生成されます。