第25回 ゆまラボ専用の404ページを作る―存在しないURLから記事へ戻れる導線を追加

存在しないURLでブラウザ標準の404だけが表示されていたため、Astroの404.astroを追加しました。SiteLayoutを再利用し、トップページ・記事一覧への導線、Cloudflare Workersで404を返す構成、ローカルと公開画面の確認まで記録します。

執筆:ゆまラボ運営者

公開:更新:
第25回 ゆまラボ専用の404ページを作る―存在しないURLから記事へ戻れる導線を追加

第24回では、記事本文のコードブロックへコピーボタンを追加し、TOPページの連載表示も変更した。

今回は通常の記事ページではなく、存在しないURLへアクセスしたときの表示を変更する。

ゆまラボにはこれまで専用の404ページがない。存在しないURLを開くと404自体は返るものの、表示されるのはサイトのヘッダーやフッターがない簡素なエラー画面。

404は正常な導線から開くページではない。ただ、URLの入力ミス、古いリンク、削除したページなどから到達する可能性はある。記事数も増えてきたため、そこでサイトとのつながりが切れる状態は変更しておくことにした。

存在しないURLではサイト内への導線がなかった#

修正前に、実際には存在しない次のURLへアクセスした。

https://bringain.com/404-test-before-custom-page/

表示は次の状態。

ゆまラボ専用404ページを作る前に存在しないURLへアクセスした画面

ブラウザには「この bringain.com ページが見つかりません」と表示され、HTTP ERROR 404になっている。

404として処理されている点は問題ない。ただし、この画面にはゆまラボのロゴも通常のナビゲーションもない。

ここから記事を読み続ける場合、一度URLを入力し直すか、ブラウザの戻る操作を使う必要がある。

今回変更したいのは404というレスポンスそのものではない。

存在しないURL

HTTP 404

ゆまラボの404ページを表示

トップページまたは記事一覧へ移動できる

この状態にする。

先に404ページの役割を確認した#

実装前には、単発記事の404ページは必要?Astroで作るエラーページとユーザーを戻す導線で、404ページをどう扱うかを確認した。

方針は、存在しないURLには404を返したまま、ユーザーがサイト内へ戻れるようにすること。正常ページへ見せかけるリダイレクトは使わない。

ゆまラボで必要な表示も複雑にはしない。

  • ページが見つからないことを明示する
  • 通常のヘッダーとフッターを表示する
  • トップページへ戻れるようにする
  • 記事一覧へ移動できるようにする

検索結果や人気記事を404専用に追加することも考えられるが、今回はそこまで広げない。

404ページは情報を詰め込む場所ではなく、現在のページが存在しないことと、次に移動できる場所が分かればよい。

Astroの404.astroを追加する#

実装前のプロジェクトを確認すると、Astroは7.3.1src/pages/404.astrosrc/pages/404.mdはどちらも存在していなかった。

Astroではsrc/pages/404.astroを作成すると、ビルド時にdist/404.htmlが生成される。

今回追加したファイルは1つだけ。

src/pages/404.astro

公開版では、既存のSiteLayoutをそのまま使っている。

主要部分は次の形になった。

---
import SiteLayout from '../layouts/SiteLayout.astro';
import { SITE_TITLE } from '../consts';

const title = 'ページが見つかりません';
const description = 'お探しのページは見つかりませんでした。ゆまラボのトップページや記事一覧から記事をお探しください。';
---

<SiteLayout title={`404 ${title} | ${SITE_TITLE}`} description={description}>
  <main>
    <section class="not-found" aria-labelledby="not-found-title">
      <p class="error-code">404</p>
      <h1 id="not-found-title">{title}</h1>
      <p class="description">
        お探しのページは、URLが変更されたか、削除された可能性があります。<br />
        トップページや記事一覧から記事をお探しください。
      </p>
      <nav class="return-links" aria-label="404ページからの移動先">
        <a href="/">トップページへ戻る</a>
        <a href="/blog/">記事一覧を見る</a>
      </nav>
    </section>
  </main>
</SiteLayout>

SiteLayoutを使うため、404専用にヘッダーやフッターを作り直す必要はない。現在のロゴ、上部ナビゲーション、サイト内検索、フッターが通常ページと同じ構成で表示される。

本文だけを404用に差し替えている。

CSSも404ページ内へ閉じた小さな指定にした。公開版では、本文幅、余白、404表示、見出し、説明、戻りリンクの6つに限定している。

既存の共通CSSやコンポーネントは変更していない。

Cloudflare Workers側の設定はすでに入っていた#

ゆまラボはAstroの静的出力をCloudflare Workersで公開している。

404ページを追加するだけでなく、Cloudflare側が存在しないURLを404.htmlとして扱える状態かも確認した。

wrangler.jsoncには、今回の実装前から次の設定が入っていた。

{
  "assets": {
    "not_found_handling": "404-page"
  }
}

そのため、今回はwrangler.jsoncを変更していない。

処理としては、AstroとCloudflareで次のようにつながる。

src/pages/404.astro

npm run build

dist/404.html

存在しないURLへアクセス

Cloudflare Workersの404-page処理

404.htmlをHTTP 404として返す

ここで確認したいのは、404風の画面を200 OKで返す状態にしないこと。

今回のローカル確認では、Astro previewとWranglerの両方で存在しないURLがHTTP 404になった。

正常な//blog/は200のまま。404ページを追加したことで通常URLの応答が変わっていないことも確認している。

ビルドとローカル404を確認する#

正式なビルドは従来どおりnpm run buildを使用した。

npm run build

実装後のビルドでは166ページが生成され、Pagefindは50ページをインデックスした。

166 page(s) built
Pagefind: Indexed 50 pages

今回の変更によるビルドエラーは発生していない。

ローカルでは、存在するURLと存在しないURLを分けて確認した。

/                              → 200
/blog/                         → 200
/404-test-before-custom-page/  → 404

Wrangler側でも同じ確認を行い、存在しないURLは404になった。

比較検証ではGPT-5.6 LunaとGPT-6 Astraの両方に同じBASE_COMMITから実装させたが、どちらの実装でもsrc/pages/404.astroだけを追加し、ビルドと404レスポンスを確認できた。

この比較結果は、継続更新しているCodexでAstro改修をLunaとAstraに任せて比較―小さな改修に高性能モデルは必要なのか?へ検証結果として追加する。

第25回ではモデル比較そのものではなく、公開した404ページの実装内容を残す。

公開サイトで404ページを確認する#

実装を公開したあと、修正前と同じURLをもう一度開いた。

https://bringain.com/404-test-before-custom-page/

公開後はこちらの表示になった。

ゆまラボ専用404ページを公開した後に存在しないURLへアクセスした画面

修正前のブラウザ標準のエラー画面から、ゆまラボの通常レイアウトを使ったページへ変わっている。

画面には、

404
ページが見つかりません

を表示し、その下に、

トップページへ戻る
記事一覧を見る

の2つのリンクを置いた。

ヘッダーにはHome、記事一覧、カテゴリ、連載、タグ、Aboutとサイト内検索があり、フッターにも既存の固定ページへの導線が残っている。

404本文へリンクを大量に追加しなくても、通常のサイトナビゲーションを再利用することで他のページへ移動できる。

公開画面の表示は確認できた。

HTTPステータスについては、今回保存した公開後画像だけから数値を確認できるわけではないため、記事中ではローカルのAstro previewとWranglerで404を確認した結果と区別して扱う。

同じ条件でLunaとAstraにも実装させた#

今回の404追加は、Codexのモデル比較用タスクとしても使用した。

開始地点は同じコミットに固定した。

BASE_COMMIT
9e1d2e67be253e660303ec9a143ca62497f844f8

そこから別ブランチを作成している。

experiment/404-page-luna
experiment/404-page-astra

両方へ同じ実装要件を渡し、片方の実装をもう片方へ引き継がない条件にした。

Lunaは93行、Astraは30行の404.astroを作成した。どちらも必要な機能は満たしているが、Lunaは404表示を大きく中央へ配置し、戻り先をボタン風にする構成。Astraは通常ページに近い余白とテキストリンクに絞る構成になった。

今回公開した画面は、Astra側で作成した文言とレイアウトに一致している。

モデルごとの所要時間や利用枠の変化は第25回には広げず、比較記事側へまとめる。

404ページの変更点#

今回変更したサイト本体のファイルはsrc/pages/404.astroだけになった。

修正前
存在しないURL

ブラウザ側の簡素な404表示

サイト内への導線なし

修正後
存在しないURL

HTTP 404

ゆまラボの共通レイアウトで404を表示

トップページ・記事一覧へ移動可能

wrangler.jsoncにはすでにnot_found_handling: "404-page"が設定されていたため、Cloudflare Workers側の追加変更はしていない。

404ページを作ったことで存在しないリンク自体がなくなるわけではない。

次は、記事内に残ったリンク切れを公開前に検出できるよう、ビルド時のチェックを追加する。

参考#