個人サイトを GitHub Pages に載せたあと、Search Console でインデックスが進まなかった。理由を開くと「リダイレクトエラー」が並んでいた。

末尾スラッシュの付け方と、サイトマップに書いた URL が噛み合っていなかった。Astro の設定とサイトマップ生成を同じルールに揃えたら、こちらでは収まった。

何が起きていたか

GitHub Pages は多くの場合、/foo/barfoo/bar/index.html として配信する。/foo/bar(末尾スラッシュなし)で開くと /foo/bar/ へ 301 される構成になりやすい。

サイトマップや canonical が https://example.com/foo/bar のままだと、提出した URL とクロール後の最終 URL が一致しない。Search Console はそれをリダイレクトまわりの不整合として扱う。

やったこと(方針)

ページ本体・canonical・サイトマップの <loc> を、ブラウザで実際に着地する URL に揃えた。このサイトでは末尾スラッシュ付きに統一している。

  1. Astro で trailingSlash: 'always' を指定する
  2. ビルド後に回しているサイトマップ生成で、ルート以外の URL に末尾スラッシュを付ける

1. Astro の設定

astro.config.mjs に次を入れる(site は自分のドメインに置き換え)。

import { defineConfig } from 'astro/config';

export default defineConfig({
  site: 'https://example.com',
  base: '/',
  // GitHub Pages は directory 形式(/path/index.html)のため /path が /path/ にリダイレクトされる。
  // サイトマップ・canonical と実 URL を一致させ、Search Console のリダイレクトエラーを防ぐ。
  trailingSlash: 'always',
});

2. サイトマップの URL 形式

このサイトでは @astrojs/sitemap の代わりに、ビルド後の dist/ を走査して sitemap-v3.xml を出すスクリプトを使っている。pathToUrl だけ抜き出すと、次のイメージになる。

function pathToUrl(path) {
  // trailingSlash: 'always' に合わせ、ルート以外は末尾スラッシュを付与
  const p = path === '/' ? '' : path.endsWith('/') ? path : `${path}/`;
  return new URL(p || '/', site).href;
}

ルート / だけは二重スラッシュにならないよう分けている。別のジェネレータを使う場合も、出力 URL を本番で開いて最終表示と突き合わせておくとよい。

デプロイ後の確認

  • 任意の記事ページを開き、アドレスバーが末尾スラッシュ付きになっているか
  • 公開中のサイトマップの <loc> がそれと同じ形式か
  • Search Console の URL 検査で、選んだ URL が「インデックス登録済み」に落ち着くか(反映は数日かかることもある)

関連

サイト全体の立ち上げは GitHub Pages を作成して公開してみた に書いてある。SEO の方針はリポジトリの README にも短く載せている。

よくある質問

Search Console の「リダイレクトエラー」はなぜ起きる?
提出 URL(例: 末尾スラッシュなし)と、サーバーが返す最終 URL(末尾スラッシュ付き)が一致しないと、リダイレクトエラーとして出る。GitHub Pages は /path を /path/ へ 301 するので、サイトマップや canonical がどちらか一方の形に偏っていると起きやすい。
Astro ではどう直す?
astro.config.mjs で trailingSlash: 'always' を指定し、配信される URL(末尾スラッシュ付き)にページと canonical を揃える。サイトマップを自前で出しているなら、loc も同じルールで末尾スラッシュを付ける。