SEO のための Next.js vs Astro(2026):どちらを選ぶべきか?
Next.js と Astro を SEO 観点で誇張なしに実践比較 — レンダリング、パフォーマンス、i18n、そしてそれぞれが勝るケース。
- Next.js
- Astro
- Comparison
Next.js も Astro も、どちらも問題なく上位表示できます。Google はどちらのフレームワークが生成するサーバーレンダリング済み HTML も文句なくインデックスしますし、「SEO にはどちらのフレームワークが優れているか」という問いは、「Google が密かにどちらを優遇しているか」という意味で読むなら間違った問いです。正しい問いはもっと狭く、もっと有用です。あなたが作ろうとしているサイトの種類を前提として、どちらのフレームワークなら、良い SEO が最小の抵抗で実現できる道になるか?
これは開発者目線の比較です。実際のレンダリングパイプライン、デフォルトでブラウザに何が送られるか、Core Web Vitals がどう落ち着くか、そして hreflang や構造化データという地味だが決定的な作業をそれぞれがどう扱うかを見ていきます。党派的になることはありません — ただトレードオフとコードを扱います。
TL;DR — 一行の結論
コンテンツサイトやマーケティングサイト(ブログ、ドキュメント、ランディングページ、プログラマティック SEO)を作るなら、Astro が箱から出してほぼゼロ JS の HTML を提供し、Core Web Vitals をうっかり台無しにする余地を最小化してくれます。コンテンツ層を付け足したインタラクティブなアプリケーション(ダッシュボード、マーケティング面を持つ SaaS、高度なパーソナライゼーションを伴う EC)を作るなら、Next.js がアプリ全体に対して一つのメンタルモデルを与え、動的でなければならないページのために成熟した SSR/ISR を提供します。
| 観点 | Astro | Next.js(App Router) |
|---|---|---|
| デフォルトのレンダリング | SSG(プリレンダリング済み HTML) | SSR / RSC(リクエストごとにサーバーレンダリング) |
| デフォルトでブラウザに送る JS | 約 0 KB(アイランドのみ) | React ランタイム + RSC ペイロード |
| 動的レンダリング | SSR アダプター、オンデマンド | SSR、ISR、ストリーミング、RSC — ファーストクラス |
| Core Web Vitals のデフォルト | 優秀(ハイドレーションが少ない) | 良好だが、退行しやすい |
| i18n | ルーティング組み込み + 手動の hreflang | i18n 設定(Pages)/ 手動(App)+ hreflang |
| 構造化データ | .astro テンプレートにインライン | コンポーネント内 / generateMetadata にインライン |
| 向いている用途 | コンテンツ & マーケティングサイト | コンテンツを伴うインタラクティブアプリ |
| 学習コスト | HTML/JS を知っていれば低い | 中程度(RSC のメンタルモデル) |
どちらの選択もランキングのペナルティにはなりません。違いは、ページを高速かつクロール可能に保つためにどれだけの注意深さが必要かという点です。
🧑💻 開発者視点:フレームワーク自体がランキングを失わせることはまれです。ランキングを失わせるのは、一段落のテキストを描画するために 400 KB の JS バンドルを送ってしまうこと、あるいは一つのインタラクティブなウィジェットだけが必要なのにページ全体をハイドレーションしてしまうことです。Astro はそうしたミスを起こしにくくします。Next.js は起こしやすくします — しかし同時に、それを避けるためのツールも与えてくれます。
レンダリングモデル
SEO は一つの問いから始まります。クローラーは最初の HTML レスポンスで何を受け取るか? Google は JavaScript を実行しますが、レンダリングは遅延され予算が割り当てられた第二の波です — つまりハイドレーション後にしか存在しないコンテンツは、レンダーキューが表に出してくれることに賭けているコンテンツです。(このパイプラインは JavaScript SEO ガイド で詳しく扱っています。)
Astro:アイランドを伴う静的優先
Astro のデフォルトは**静的サイト生成(SSG)**です。ビルド時に .astro コンポーネントを実行し、完全な HTML を生成し、そして — これが肝心な点ですが — client:* ディレクティブでコンポーネントを明示的にハイドレーション対象にしない限り、フレームワークの JavaScript を取り除きます。これが「アイランドアーキテクチャ」です。ページは静的 HTML で、インタラクティブな部分だけがハイドレーションされたアイランドになります。
---
// src/pages/blog/[slug].astro — ビルド時に実行され、クライアントには送られない
const { slug } = Astro.params;
const post = await getPost(slug);
---
<article>
<h1>{post.title}</h1>
<div set:html={post.html} />
<!-- このカウンターだけが JS を送る。残りは不活性な HTML。 -->
<LikeButton client:visible postId={post.id} />
</article>
クローラーは最初のバイトで完全に組み上がった記事を受け取ります。待つべき第二のレンダリングの波はありません。なぜなら、描画すべきものが残っていないからです。コンテンツにとって、これ以上ないほど理想的です。Astro はアダプター(@astrojs/node、Cloudflare、Vercel)を使って、ルートが本当にリクエストごとのデータを必要とするときに SSR も行えるので、「静的優先」は「静的専用」を意味しません。
Next.js:サーバーコンポーネントとリクエストごとのレンダリング
App Router を使う Next.js はReact Server Components をデフォルトとします。ページはサーバー上(または静的ルートではビルド時)にレンダリングされ、HTML をブラウザに送るとともに、React がクライアントコンポーネントを照合・ハイドレーションできるようにする RSC ペイロードを送ります。最初のレスポンスで HTML が得られる — クロールには良い — のですが、ページは同時に React ランタイムも送り、クライアント側で再ハイドレーションします。
Next.js はより豊富なレンダリングモードのメニューを与え、ルートごとに選択します。
- 静的(SSG) —
export const dynamic = 'force-static'、あるいは単に動的データを使わない場合。ビルド時にプリレンダリングされる。 - SSR — リクエストごとにレンダリング。ユーザー、地域、時間によって変わるコンテンツ向け。
- ISR —
export const revalidate = 3600。静的に配信し、バックグラウンドで再生成する。頻繁に変わるが毎リクエストではない大規模コンテンツサイトに最適。
// app/blog/[slug]/page.tsx — Server Component、サーバー上で実行される
export const revalidate = 3600; // ISR: 最短でも 1 時間ごとに再生成
export async function generateStaticParams() {
const posts = await getAllSlugs();
return posts.map((slug) => ({ slug }));
}
export default async function Page({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug);
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</article>
);
}
💡 ヒント:SEO にとって危険な Next.js のパターンは、メインコンテンツを
useEffectで取得するクライアント側の'use client'ページです。そのコンテンツは最初の HTML には見えず、完全に Google のレンダリングの波に依存します。ルートの主要コンテンツがサーバーレンダリング可能なら、サーバーレンダリングしましょう。
実践的な要点:どちらも、モダンで推奨される構成では、デフォルトでインデックス可能な HTML を配信します。 Astro はクライアントフレームワークを一切付けずに配信し、Next.js はハイドレーションのステップとともに配信します。このたった一つの違いが、以降の大部分を決定づけます。
パフォーマンス & Core Web Vitals
Core Web Vitals(LCP、INP、CLS)はランキングシグナルであり、さらに重要なのは、実際のユーザーが快適に過ごせているかどうかの代理指標であることです。フレームワークの選択がもっとも明確に表れるのは、どれだけの JavaScript が送られ、そのうちどれだけがページがインタラクティブになる前に実行されなければならないかという点です。
デフォルトのペイロード
典型的な Astro のコンテンツページは、そのアイランドのための JS だけを送ります — 純粋な記事では文字どおりゼロのことも多いです。典型的な Next.js App Router のページは、React ランタイムに加えて RSC フライトペイロード、さらに各クライアントコンポーネントのコードを送ります。それは「肥大化」ではなく — React アプリのコストです — しかし 95% が文章のページでは、使わないインタラクティブ性のために対価を払っていることになります。
| ページの種類 | Astro の典型的なクライアント JS | Next.js の典型的なクライアント JS |
|---|---|---|
| 静的な記事、ウィジェットなし | 約 0 KB | 約 80〜110 KB(ランタイム + RSC) |
| 記事 + コメントウィジェット一つ | 約 15〜30 KB(アイランド一つ) | 約 90〜130 KB |
| 高度にインタラクティブなダッシュボード | 大量にハイドレーションすると Next と同程度 | 約 150 KB 以上(本領発揮の領域) |
数値は依存関係によって変わります — next build の出力や Astro のバンドルレポートで自分のビルドを計測してください — しかし傾向は一貫しています。Astro はゼロ付近から始まり、頼んだところにだけ JS を足します。Next はランタイムの下限から始まり、そこから増えていきます。
ハイドレーションのコストと INP
LCP は主に最大の要素を素早く描画することに関わり — どちらのフレームワークもサーバーレンダリングするときはこれをうまくこなします。より鋭い分かれ目は INP(Interaction to Next Paint)で、これはメインスレッドの作業にペナルティを与えます。大きな React ツリーをハイドレーションするとメインスレッドがブロックされ、ローエンドのモバイルでは最初のインタラクションが遅延します。Astro のアイランドは独立して遅延的にハイドレーションされる(client:visible、client:idle)ため、メインスレッドはより長く空いたままになります。
⚠️ 注意:速いフレームワークが遅いサイトを救うことはありません。最適化されていないヒーロー画像、レンダリングをブロックするサードパーティスクリプト、ウェブフォントによるレイアウトシフトは、どちらのフレームワークでも CWV を台無しにします。フレームワークのせいにする前に、実際の監査(PageSpeed Insights、Lighthouse、または当サイトの Core Web Vitals ガイド)を実施してください。
ビルド済みページに対する簡単なチェックで、実際に何が送られているか検証しましょう。
# ページが実際にリクエストする JS の本数を数える
curl -s https://your-site.com/blog/some-post/ \
| grep -oE 'src="[^"]+\.js"' | wc -l
# またはクローラーが見る最初の HTML を調べる — コンテンツはそこにあるか?
curl -s https://your-site.com/blog/some-post/ | grep -c "<h1"
コンテンツ vs アプリ
ここで通常、判断は自ずと定まります。あなたのサイトが何であるかを問いましょう。
コンテンツサイトやマーケティングサイトは Astro が勝ちます。 ブログ、ドキュメント、変更履歴、ランディングページ、そしてプログラマティック SEO ページ(数百〜数千のテンプレート化された URL)は、ほとんどがテキストと画像で、ときどきインタラクティブ性がある程度です。Astro のコンテンツコレクションは、型付きの frontmatter、Markdown/MDX、そしてゼロ JS の出力を与えてくれます。CMS ライトなセットアップのオーサリング体験と、手書き HTML のパフォーマンスの両方が手に入ります。
Astro のコンテンツコレクション — 型付き、ビルド時、クライアント JS ゼロ
src/content/
blog/ ← MDX + frontmatter スキーマ(Zod)
config.ts ← defineCollection() がビルド時にすべての記事を検証
インタラクティブなアプリケーションは Next.js が勝ちます。 中核となるプロダクトがアプリ — 認証付きダッシュボード、リアルタイムデータ、複雑なフォーム、状態を持つフロー — であり、その周辺にあるマーケティングやコンテンツ面で SEO が重要な場合、Next.js なら全体を一つのフレームワーク・一つのデプロイで構築できます。二つのスタック(Astro のマーケティングサイトと別個の React アプリ)を運用することと、その間にあるルーティング/認証の継ぎ目を避けられます。App Router の ISR と SSR は、純粋な SSG モデルでは絶えず再ビルドを強いられるような、本当に動的で SEO に関わるページ(ライブ価格を表示する商品ページ、ロケーションページ)も扱えます。
グレーゾーンは、多少の動的性を持つ EC や大規模コンテンツサイトです。どちらでも機能します。ページが大規模にリクエストごとの状態(在庫、パーソナライゼーション)を反映しなければならないなら Next.js を選び、カタログがほぼ静的で、少数の動的ルートを再ビルドするかオンデマンド SSR で扱えるなら Astro を選びましょう。
i18n & 構造化データ
国際 SEO の生死は hreflang にかかっており、リッチリザルトは JSON-LD に宿ります。どちらのフレームワークもこれを完全に代わりにやってはくれません — マークアップはあなたの責任です — が、ルーティングのサポートは異なります。
hreflang
どちらのフレームワークも、相互参照する hreflang の link タグをあなたが出力することを前提とします。Astro には組み込みの i18n ルーティング(ロケールプレフィックス、デフォルトロケール設定)があり、代替 URL の生成を素直にしてくれます。Next.js の Pages Router には i18n 設定がありましたが、App Router はフォルダベースのロケールセグメント(app/[locale]/...)に加えて next-intl のようなライブラリへとあなたを誘導します。いずれの場合も、タグは自分で生成します。
<!-- 同じタグ一式が、ページのすべての言語バージョンに置かれるべき -->
<link rel="alternate" hreflang="en" href="https://ex.com/en/blog/post/" />
<link rel="alternate" hreflang="fr" href="https://ex.com/fr/blog/post/" />
<link rel="alternate" hreflang="x-default" href="https://ex.com/en/blog/post/" />
💡 ヒント:もっともよくある
hreflangのバグは、非相互的なアノテーションです — ページ A は B を指しているのに、B は A を指し返していない。一つの信頼できる情報源(ロケール → URL のマップ)からクラスター全体を生成し、すべてのバリアントにレンダリングしましょう。詳しい解説は国際 SEO ガイドにあります。
構造化データ(JSON-LD)
JSON-LD は単なる script タグなので、どちらのフレームワークも本質的には同じように扱います — 違いはどこに置くかだけです。Astro ではテンプレートにインラインで書き、Next.js ではコンポーネントからレンダリングするか generateMetadata の中で組み立てます。
---
// Astro: frontmatter でオブジェクトを組み立て、script タグとしてレンダリング
const schema = {
"@context": "https://schema.org",
"@type": "BlogPosting",
headline: post.title,
datePublished: post.pubDate.toISOString(),
};
---
<script type="application/ld+json" set:html={JSON.stringify(schema)} />
// Next.js: Server Component から JSON-LD をレンダリング
export default function Page({ post }) {
const schema = {
"@context": "https://schema.org",
"@type": "BlogPosting",
headline: post.title,
datePublished: post.pubDate,
};
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
);
}
フレームワークに関わらず、Google の Rich Results Test で出力を検証しましょう — 必須プロパティが欠けていても静かに失敗し、リッチリザルトは決して得られません。
どちらをいつ選ぶか
シナリオ別の具体的な指針:
- ブログ、ドキュメント、マーケティングサイト → Astro。 ゼロ JS がデフォルト、コンテンツコレクション、必要な規律が最小で得られるベストエフォートな CWV。
- 大規模なプログラマティック SEO(数千のテンプレートページ) → ページがほぼ静的なら Astro、頻繁または毎リクエストの鮮度が必要なら ISR を使った Next.js。
- マーケティングサイトとアプリを持つ SaaS → 一つのスタックがよければ Next.js、マーケティングページの最大速度を求め二つのデプロイを厭わないなら Astro でマーケティング + あなたのアプリフレームワーク。
- EC → 大規模なリクエストごとの在庫/価格/パーソナライゼーションには Next.js、ほぼ静的なカタログには Astro。
- SEO が二の次の高度にインタラクティブなアプリ → Next.js。 ここでは SEO は問題になりません。DX で選びましょう。
- React を深く理解し速くリリースするチーム → クライアント JS について規律を保つ限り、コンテンツであっても Next.js が摩擦を下げます。
🧑💻 開発者視点:人気があり、まったく妥当なパターンは両方使うことです — マーケティング/ブログのサブドメインや
/blogパスには Astro を、app.*には Next.js(またはあなたの SPA)を。SEO が重要なところには Astro のコンテンツパフォーマンスを、そうでないところには React のインタラクティブ性を得られます。コストは二つのビルドと共有するデザインシステムです。
まとめ
Google が報いるフレームワークを探すのはやめましょう — そんなものは存在しません。Next.js も Astro も、モダンな方法で構成すればクロール可能でランキング可能な HTML を生成します。本当の判断は、デフォルトの挙動と失敗のしかたに関するものです。Astro は高速でゼロ JS のコンテンツページをデフォルトかつ怠け者の道にします。Next.js は統一されたインタラクティブなアプリケーションをデフォルトにし、規律を投じれば動的ページを SEO フレンドリーに保つためのレンダリングモードを与えてくれます。
サイトがコンテンツであるなら Astro を選びましょう。サイトがコンテンツも持つアプリなら Next.js を選びましょう。そして迷ったら、議論する前に、実際のビルドで最初の HTML と送られる JS を計測しましょう。
次のステップ:
- Astro SEO ガイド — SEO 向けのコンテンツサイトを最初から最後までセットアップする。
- JavaScript SEO とレンダリング — Google が JS をどうレンダリングするか、そして SSG/SSR/ISR をどう選ぶか。