JekyllのSEO

Jekyllサイトを検索向けに最適化する方法 — 静的HTMLがデフォルトでクローラーに優しい理由、さらにjekyll-seo-tagとjekyll-sitemapプラグイン、パーマリンク、コレクション、robots.txt、GitHub Pagesのプラグインホワイトリストについて。

初回公開:2026年6月26日 · 最終更新:2026年8月20日 · Advanced
言語
このページには証拠シグナルが1件あります

Jekyllはフラットな静的HTMLを出力するため、クローラーはJavaScriptのレンダリング待ちなしで最初の取得で完全なコンテンツを取得できます。つまり、SEO作業はフレームワークと戦うことではなく、設定の問題です。jekyll-seo-tag(タイトル、説明、正規URL、Open Graph、Twitter Card、JSON-LD)とjekyll-sitemap(sitemap.xml)をインストールし、_config.ymlでurl:を設定しないと、どちらも壊れた出力になります。常緑コンテンツにはクリーンなパーマリンク(日付ベースではなく/:title/)を選びましょう。robots.txtは自分で作成してください — Jekyllは作成しません。GitHub Pagesの2つの落とし穴に注意:プラグインホワイトリスト(GitHub Actionsビルドなしで実行されるのは固定セットのみ)と、プロジェクトサイトでのbaseurlの誤設定で、すべての正規URLが壊れます。

TL;DR — Jekyllはビルド時にフラットな静的HTMLを生成するため、コンテンツは最初のクロールで生のレスポンスに含まれます。Web Rendering ServiceもWave 2の遅延もありません。SEOの作業はアーキテクチャではなく設定です。jekyll-seo-tag(タイトル、説明、canonical、OG、Twitter Card、JSON-LD)とjekyll-sitemapsitemap.xml)をインストールします。どちらも_config.ymlurl:が必須で、ないと壊れた出力になります。常設コンテンツには日付ベースではなくクリーンなパーマリンク(/:title/)を使用します。GitHub Pagesの2つの落とし穴が支配的です:プラグインのホワイトリスト(GitHubは--safeでビルドします。ホワイトリスト外のプラグインはGitHub Actionsでのビルドが必要)と、プロジェクトサイトでの**baseurlの欠落で、生成されるすべてのcanonical URLが壊れます。GitHub Pagesはまた、実行するプラグインだけでなく、特定のプラグインバージョン**(コア3.10.0、古いjekyll-seo-tag/jekyll-sitemapリリース)も固定します。コレクションはoutput: trueがないとレンダリングされません。ドラフト、未来日付の投稿、published: falseのドキュメントは通常のビルドから除外され、--incrementalは実験的です。本番デプロイには使用しないでください。また、robots.txtは自動生成されません。自分で作成してください。

Jekyllの静的出力がSEOに良い理由

Jekyllは静的サイトジェネレーターです。MarkdownとLiquidテンプレートをビルドステップで処理し、リクエストの前に一度だけ完成したHTMLを出力します。このタイミングこそがSEO上の利点のすべてです。 Evidence for this claim Jekyll processes text and templates into static files during a build. Scope: Jekyll build architecture. Confidence: high · Verified: Jekyll documentation

Googleのパイプラインはクロール→レンダリング→インデックスであり、JavaScriptのレンダリングは”別のステップ”としてキューに入ります。これは一般に「2ウェーブ」プロセスと呼ばれるものです。ウェーブ1は生のHTMLを取得し、テキストとリンクを即座にインデックスします。ウェーブ2はページをWeb Rendering ServiceにキューイングしてJavaScriptを実行します。これはクロール予算に応じて「数秒から数週間」後になります。Jekyllでは、ウェーブ1にすでにすべてのコンテンツが含まれています。本文をレンダリングするためのJavaScriptは不要です。ウェーブ1=ウェーブ2です。レンダリングの遅延も、レンダリング予算の消費もありません。これは、あらゆる静的サイトジェネレーターがインデックス可能性において最もリスクの低いアーキテクチャであるというのと同じ論拠です。

下流の利点は次のとおりです:

  • より速いTTFB。 プリビルドされたファイルがCDN(GitHub PagesはFastlyの背後にあり、Netlify/Vercelには独自のエッジがあります)から配信されるため、データベースクエリもサーバー処理もありません。LCPやその他のCore Web Vitalsに良い影響を与えます。
  • コンテンツに必要なJSペイロードがない → ハイドレーションするSPAよりもFCPとLCPが向上します。
  • CDN層での適切なHTTPステータスコード。クライアント側のエラーハンドリングではありません。

しかし、それらのどれも基本を変えるものではありません。静的サイトでもメタタグ、サイトマップ、canonical URL、構造化データ、優れたコンテンツが必要です。 Jekyllの出力はクローラーに優しいですが、メタデータはあなた次第です。

GitHub PagesとJekyll SEO

最も一般的なJekyllのデプロイ先はGitHub Pagesです。Pagesが有効なブランチにプッシュすると、GitHubがサイトを自動ビルドします。その利便性には、SEOに関連する制約が伴います。

プロジェクトサイトとユーザー/組織サイト — URLの決定

  • username.github.io/repo-nameプロジェクトサイト)は、無関係な数千の他のサイトと共有されるサブドメインに置かれます。ドキュメント、デモ、URL自体がブランドを伝える必要のない個人プロジェクトには問題なく機能します。
  • カスタムドメインCNAMEをGitHub Pagesに向ける)は、サイトを自分が管理するURLに置き、GitHubがHTTPSを自動プロビジョニングします。ドメイン自体が重要なサイト(ビジネスサイト、オーディエンスを構築しているブログ)では、最初からカスタムドメインを使うことで、後でのドメイン移転を避けられます。

カスタムドメインへの移行を予定しているなら、早めに設定しておきましょう。 ドメイン移行には301リダイレクト(jekyll-redirect-from が対応)と、インバウンドリンクや蓄積されたシグナルが旧URLを指す期間が伴います。後から切り替えるのではなく、最初から最終ドメインを選べば、避けられる無駄な作業です。これは移行計画の議論であり、github.io サブドメイン自体がペナルティを受けるという主張ではありません。

baseurl — プロジェクトサイトで最も多い正規化バグ

プロジェクトサイトはサブフォルダ(/repo-name/)配下に置かれます。_config.ymlbaseurl: /repo-name を設定しないと、jekyll-seo-tag が生成するすべての正規URL(および内部リンク)がサブフォルダを欠いた誤ったものになります。これはJekyllプロジェクトサイトで最も一般的な正規URLバグです。(ドメインルートで提供されるユーザー/組織サイトでは baseurl は不要です。)

プラグインホワイトリスト

GitHub Pages は Jekyll を --safe フラグ付きで実行し、固定されたプラグインセットのみを許可します。 Evidence for this claim GitHub Pages builds Jekyll in safe mode and supports a documented set of plugins. Scope: GitHub Pages hosted builds. Confidence: high · Verified: GitHub Pages: Jekyll plugins SEO関連でホワイトリストに登録されているもの:

  • jekyll-seo-tag
  • jekyll-sitemap
  • jekyll-redirect-from ✓(URL変更時の301リダイレクト用)
  • jekyll-paginate

ホワイトリストに登録されていない(そして静かに実行されない、またはエラーになる)もの:

  • jekyll-last-modified-at — ファイルのタイムスタンプから正確なサイトマップ <lastmod> を生成するために必要
  • カスタム構造化データプラグイン
  • _plugins/ フォルダに置かれたもの

問題はどのプラグインかだけでなく、どのバージョン

GitHub Pages は実行するプラグインを制限するだけでなく、各プラグインの正確なバージョンを固定し、そのビルド環境自体も古いJekyllに固定されています。依存関係リスト の最終更新時点で、ホストされたビルドは Jekyll 3.10.0 を jekyll-seo-tag 2.8.0、jekyll-sitemap 1.4.0、jekyll-feed 0.17.0 で実行しています。一方、jekyllrb.com の公式ドキュメントは現在のアップストリームリリースである 4.4.1 を説明しています。プラグインの最新READMEに記載されている動作が、GitHub Pages が実際に実行するバージョンに存在するとは限りません。特定のフラグや出力に依存する前に、pages.github.com/versions.json で固定バージョンを確認してください。GitHub Actions ビルドもこれを回避します。Gemfile を制御できるため、GitHub の固定セットではなく、自分で固定したバージョンを取得できます。

GitHub Actions による回避策

ホワイトリストの修正は「gemを追加する」ことではなく、GitHub にビルドを任せるのをやめることです。CI で Jekyll を自分で実行し(actions/jekyll-build-pages、またはローカルでビルドして _site/peaceiris/actions-gh-pages でデプロイブランチにプッシュ)、ホワイトリストは適用されなくなります。これで任意のプラグインが実行でき、GitHub の固定セットを引き継ぐのではなく、Jekyll とプラグインのバージョンを自分で選べます。

jekyll-seo-tag プラグイン

これは公式にメンテナンスされているプラグインで、Jekyll が単独では追加しない主要なメタデータのほとんどをカバーします。正確に何を出力するかは、インストールされているバージョン、_config.yml とフロントマター、そしてレイアウトが実際に {% seo %} を呼び出すかどうかによって異なります。たとえば GitHub Pages は、常に最新リリースを提供するのではなく、特定のバージョンを固定しています(詳細は後述)。お使いのバージョンの正確な出力については高度な使用法ガイド を確認し、実際に何が反映されたかを、完全だと想定せずに、自分でビルドしたHTMLをgrepして確認してください。

インストール:

# Gemfile
gem 'jekyll-seo-tag'
# _config.yml
plugins:
  - jekyll-seo-tag
<!-- _layouts/default.html, before </head> -->
{% seo %}

自動生成されるもの:

  • <title> — サイト名を追加したページタイトル(Page Title | Site Name
  • <meta name="description">description: フロントマターまたはサイトの説明から
  • <link rel="canonical">site.url + page.url から構築
  • Open Graph タグ(og:titleog:descriptionog:urlog:site_nameog:image
  • Twitter Card タグ(twitter:cardtwitter:titletwitter:descriptiontwitter:creatortwitter:image
  • JSON-LD 構造化データ(投稿には BlogPosting、ホームページには WebSite
  • ページネーションメタ(次/前のURL)

必要な _config.yml 設定 — これがないとプラグインは壊れた出力を生成します:

title: Your Site Title
description: Your site description
url: "https://yourdomain.com"   # CRITICAL — drives canonical URL generation
author:
  name: Patrick Stox
  twitter: patrickstox
  url: https://patrickstox.com  # author disambiguation
twitter:
  username: patrickstox
  card: summary_large_image

ページごとのフロントマターの上書き:

---
title: "Jekyll SEO Guide"
description: "How to optimize Jekyll sites for search engines."
image:
  path: /assets/jekyll-seo-og.png
  width: 1200
  height: 630
  alt: "Jekyll SEO diagram"
canonical_url: "https://example.com/jekyll-seo/"  # override if needed
robots: noindex   # per-page noindex
seo:
  type: BlogPosting          # schema.org type override
  date_modified: 2025-01-15  # dateModified override for JSON-LD
---

抑制(レイアウトがすでに独自の出力を行う場合):

{% seo title=false %}      <!-- suppress the <title> -->
{% seo canonical=false %}  <!-- suppress the canonical link -->

注意すべき落とし穴が1つあります。多くのミニマルテーマ(minimaを含む)は、jekyll-seo-tagが組み込まれずに配布されています。Gemfileにgemを追加しても、テーマのレイアウトが実際に{% seo %}を呼び出さない限り、何も起こりません。

jekyll-sitemapによるサイトマップ

同じインストールパターン(Gemfile + _config.yml)です。ビルドのたびに、sitemaps.org準拠のsitemap.xml/sitemap.xmlに生成します。

_config.ymlurl:が必要です — これがないと、サイトマップのエントリにドメインがありません。

<lastmod>の制御(優先順位順):

  1. フロントマターのlast_modified_at:(最良 — 明示的な制御)
  2. 投稿の作成日(フォールバック — 後で更新されるエバーグリーンコンテンツではしばしば不正確)
  3. ファイルシステムの変更日(ホワイトリストにないjekyll-last-modified-atが必要)

ベストプラクティス: すべての投稿にlast_modified_at: YYYY-MM-DDを追加し、コンテンツを更新したときに更新してください。これが再クロールの優先順位が依存する鮮度シグナルです。

ページの除外:

# Per-page front matter
sitemap: false

# Global pattern (in _config.yml)
defaults:
  - scope:
      path: "assets/**/*.pdf"
    values:
      sitemap: false

パーマリンク設定

パーマリンクは_config.ymlでグローバルに設定されるか、フロントマターでページごとに上書きされます。

スタイルパターンSEOメモ
date(デフォルト)/:categories/:year/:month/:day/:title.html日付に依存し、投稿日が変わると壊れやすい
pretty/:categories/:year/:month/:day/:title/末尾スラッシュ、.htmlなし
none/:categories/:title.html日付の埋め込みなし
カスタム/:title/ または /:categories/:title/最も制御しやすい — エバーグリーンコンテンツに推奨

ほとんどのサイトに推奨:

permalink: /:title/
# or
permalink: /:categories/:title/

エバーグリーン投稿で日付ベースのURLを避ける理由:

  • 投稿のdate:フロントマターを変更するとURLが変わる → インバウンドリンクが壊れる。
  • 深い階層(/2019/03/14/post-title/)は、理由もなくコンテンツを埋もれさせる。
  • (ニュースやジャーナリズムでは、日付URLは問題なく期待される — これは普遍的なルールではなく、文脈に応じた判断です。)

コレクションには独自のパーマリンク設定が必要:

collections:
  case_studies:
    output: true
    permalink: /case-studies/:name/

パターン変更の警告: URLがインデックスされたら、パーマリンクスタイルを切り替えるには301リダイレクトが必要です(jekyll-redirect-fromを使用)。リダイレクトをスキップすると、リンクエクイティが損なわれ、Search Consoleで404sが発生します。

コレクションとSEO

コレクションは、投稿やページを超えたJekyllのカスタムコンテンツタイプです — ドキュメントセクション、ポートフォリオ項目、チームメンバー、ケーススタディ、FAQ。SEOを左右する2つの要件があります:

  1. output: trueを設定する必要があります。 これがないと、コレクションドキュメントは個別のHTMLファイルとしてレンダリングされず、インデックスできません。これは静かなインデックスキラーです — コンテンツはリポジトリに存在しますが、クロール可能なページにはなりません。

    collections:
      docs:
        output: true          # REQUIRED for indexable pages
        permalink: /docs/:name/
  2. 各ドキュメントにはフロントマターが必要です — 空の---ブロックでも構いません。これがないと、Jekyllはファイルをバイナリ静的ファイルとして扱います:Liquid処理なし、メタデータなし、jekyll-seo-tag統合なし。

コレクションはRSSフィードに含まれない(投稿のみ)ことに注意してください。大規模なドキュメントサイトでは、コレクションが通常は適切な構造です。

公開状態とインクリメンタルビルド

Jekyllには、ビルドされたサイトに実際に何が含まれるかを制御するいくつかの独立したスイッチがあります。これらを混同すると、静かにビルドされないページや、ドラフトや未来のコンテンツが誤って本番に公開される可能性があります:

  • 下書き_drafts/)は通常のビルドから完全に除外されます。これらは bundle exec jekyll serve --drafts(または build --drafts)をローカルで実行した場合にのみ 表示されます。実際に公開するには、投稿を実在する日付とともに _posts/ に移動します。
  • 未来の日付の投稿(現在時刻より後の date:)はデフォルトで除外されます。 _config.ymlfuture: true または --future フラグで含めることができます。 ローカルプレビューには便利ですが、本番設定で有効のままにすると、予定日ではなくビルドした時点で 予約投稿が公開されてしまいます。
  • フロントマターの published: false は、日付に関係なくドキュメントをビルドから除外します。 これは下書きや未来の投稿とは別のスイッチであり、公開予定のページをテストした後に 設定したままにしがちです。
  • インクリメンタル再生成--incremental)は、Jekyll によって 実験的 と文書化されており、 限られた依存関係グラフ(主にインクルードとレイアウト)を追跡します。site.posts やその他の コレクションデータ(タグインデックス、アーカイブ、関連投稿ロジック)を反復処理するページは、 --incremental では、基になる投稿が変更されたことを Jekyll が検出せずに古くなる可能性があります。 本番デプロイの一部として実行しないでください。公開するものには完全な bundle exec jekyll build を使用してください。

これらを信頼する前に、ローカルで使用するフラグ(--drafts--future--incremental)なしでビルドし、 _site/ の出力が公開予定のものと一致することを確認してください。デプロイパイプラインの最も安全な デフォルトは、クリーンで完全な非インクリメンタルビルドです。

Liquid を使用したカスタム head パーシャル

jekyll-seo-tag では不十分な場合は、独自の _includes/head.html を作成します。

<head>
  <meta charset="UTF-8">
  <title>
    {% if page.title %}{{ page.title }} | {{ site.title }}
    {% else %}{{ site.title }}{% endif %}
  </title>
  <meta name="description" content="
    {%- if page.description -%}{{ page.description }}
    {%- elsif page.excerpt -%}{{ page.excerpt | strip_html | strip_newlines }}
    {%- else -%}{{ site.description }}
    {%- endif -%}">
  <link rel="canonical" href="{{ page.url | prepend: site.url }}">
  {% seo %}
</head>

SEO に重要な Liquid フィルター:

  • | strip_html — 自動抜粋からタグを削除します(クリーンな説明に必須)
  • | strip_newlines — 抜粋から改行を削除します
  • | truncate: 160 — テンプレート側のオプションの文字数制限であり、Google の制限ではありません。 作成済みのページ固有の説明を優先し、レンダリングされたスニペットをプレビューしてください。 適合性はクエリ、デバイス、言語、スクリプトによって異なります。
  • | prepend: site.url — canonical タグと OG タグ用の絶対 URL を構築します
  • | date_to_xmlschema — JSON-LD の datePublished/dateModified 用の ISO 8601 日付
  • | default: fallback — 変数が nil の場合のフォールバック

jekyll-seo-tag が出力するものを超えたカスタム JSON-LD:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": {{ page.title | jsonify }},
  "datePublished": "{{ page.date | date_to_xmlschema }}",
  "dateModified": "{{ page.last_modified_at | default: page.date | date_to_xmlschema }}",
  "author": {
    "@type": "Person",
    "name": "{{ page.author.name | default: site.author.name }}",
    "url": "{{ page.author.url | default: site.author.url }}"
  }
}
</script>

robots.txt は自動生成されない

Jekyll は robots.txt作成しません。サイトのルートに自分で作成します。 Liquid がファイルを処理できるように({{ site.url }} が解決されるように)、空のフロントマターブロックを 含めます。

---
---
User-agent: *
Allow: /

Sitemap: {{ site.url }}/sitemap.xml

これがないと、robots.txt にサイトマップ参照が含まれず、一部のクローラーはそれを 発見メカニズムとして使用します。(robots.txt はインデックスではなくクロールを制御します。 詳細は クロール を参照してください。)

よくある Jekyll SEO の誤解

「Jekyll は SEO を自動的に処理する。」 静的出力はクローラーに適していますが、 メタデータには明示的な設定が必要です。デフォルトのテーマには SEO タグがまったく含まれていないことがよくあります。

「GitHub Pages は SEO に問題ない — 無料だから。」 GitHub Pages 自体は問題ありません。 静的出力はホストに関係なくクローラーに適しています。問題となるのは、プラグインのホワイトリスト (どのプラグインかだけでなく、固定されている特定のバージョン)と、ブランドが URL に依存する場合は、 github.io でオーディエンスを構築する前にカスタムドメインを決定することです。

「静的サイトにサイトマップは不要。」 Google はリンク経由でページを見つけることができますが、 サイトマップは発見を高速化し、<lastmod> シグナルを伝えます。jekyll-sitemap を使えば簡単です。

“Jekyll is dead.”(訳:「Jekyllは終わった」)という見方もありますが、実際には成熟したメンテナンス段階にあります。v4.4.1は2025年1月にリリースされました。新機能の追加は限定的でも、保守とセキュリティ対応は続いており、GitHub Pagesでも引き続きサポートされています。シンプルなブログやドキュメントには、堅実で枯れた選択肢です。

「GitHub Pages で任意のプラグインを使用できる。」 いいえ — --safe と固定のホワイトリストがあります。 解決策は GitHub Actions であり、gem を追加することではありません。

位置づけ

Jekyll は、静的サイトジェネレーター クラスター内の 6 つのジェネレーターの 1 つです。GitHub Pages のデフォルトであり、ほとんどの開発者が最初に触れるものです。Google が JavaScript をレンダリングする方法と、実際にそれが必要になる場合のより広い文脈については、JavaScript SEO ハブを参照してください。すべての SSG に適用されるビルドの鮮度の規律(静的サイトは最後のビルド時点のものに過ぎない)は Jekyll にも適用されます。編集内容は、再ビルドして再デプロイするまで検索エンジンに届きません。

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.