コンテンツにスキップ
LinkedInX

内部リンクを公開URLで検証する:ファイルの存在確認だけでは不十分だった理由

ファイルは存在しているのにリンクが壊れている

このサイトの内部リンク(サイト内の別のページへのリンク)を検証していたとき、奇妙な状況が発生しました。「リンク先のファイルが存在しているにもかかわらず、そのリンクをクリックしても正しいページに到達しない」という問題です。

原因を調べると、「ファイルのパス」と「公開されるURL」が一致していないことがわかりました。

ファイルパスと公開URLの違い

このサイトはAstro(Starlight)で構築されており、Vercelでホスティングしています。ファイルを特定の場所に置いても、公開されるURLはそのファイルパスとは異なります。

具体例で説明します。

リポジトリの中にあるファイルのパス:

src/content/docs/ja/ai/poc-to-production.md

このファイルが公開されるURL:

/ja/ai/poc-to-production/

ファイルパスにはsrc/content/docs/というプレフィックスがありますが、公開URLにはそれが含まれません。また、URLの末尾にスラッシュ(/)が付きます。

記事の中に「/src/content/docs/ja/ai/poc-to-production.mdを確認してください」というリンクを書いても、そのパスは公開URL上では存在しません。正しくは/ja/ai/poc-to-production/へのリンクが必要です。

Vercelの末尾スラッシュ処理

さらに問題を複雑にしたのが、Vercelの末尾スラッシュ(trailing slash)の処理です。

/ja/ai/poc-to-production(末尾スラッシュなし)へのアクセスを/ja/ai/poc-to-production/(末尾スラッシュあり)にリダイレクトする設定になっていました。リンクが末尾スラッシュなしで書かれていると、リダイレクトが発生し、場合によっては意図しないページに到達することがありました。

この挙動はファイルの存在確認だけでは検出できません。ファイルは存在しており、エラーも出ませんが、実際のURLの動作が期待と異なります。

解決策:公開URLを期待値として登録する

この問題を解決するために、critical-links.jsonというファイルを作成しました。

このファイルには、重要な内部リンクの「期待する公開URL」を一覧として登録します。

[
  "/ja/ai/poc-to-production/",
  "/ja/engineering/harness-engineering/",
  "/blog/what-is-harness-engineering/"
]

そしてスクリプトが、この一覧のURLに実際にアクセスできるかを確認します。ファイルの存在ではなく、公開URLへのアクセスを確認することで、ファイルパスと公開URLのずれを検出できます。

なぜファイルの存在確認だけでは不十分だったか

まとめると、ファイルの存在確認だけでは不十分だった理由は2点です。

1. ファイルパスと公開URLが異なる

静的サイトジェネレーターを使う場合、ファイルを置いた場所がそのままURLになるわけではありません。フレームワークが変換ルールを持っており、その結果として公開URLが決まります。

2. サーバー設定によるリダイレクトが影響する

末尾スラッシュのリダイレクト設定のように、サーバー(この場合はVercel)の設定がURL挙動に影響します。これはファイルの存在とは無関係に発生します。

まとめ

内部リンクの検証は、ファイルの存在確認だけでは不十分な場合があります。特にAstro(Starlight)のような静的サイトジェネレーターとVercelのホスティングを組み合わせている環境では、ファイルパスと公開URLが一致しないケースが起きます。公開URLを期待値として管理し、実際にアクセスできるかを確認するスクリプトを組み込むことで、この種の問題を検出できます。