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にテキストコンテンツがそのまま含まれます。
| 特徴 | Astro | Next.js | Gatsby |
|---|---|---|---|
| デフォルトのレンダリング | SSG(ゼロJS) | SSR | SSG |
| 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対応ページが生成されます。