静的HTMLサイトで、全ページのナビゲーションバー更新を自動化した話

共通ナビだけを一括更新する

静的HTMLサイトは軽くて扱いやすい一方で、記事数が増えると共通部品の管理が課題になります。今回は、各HTMLに直書きされていたナビゲーションバーを、共通定義から一括同期できるようにした実務ログです。

概要

Time Columnsを運用していて、ナビゲーションバーの管理が少し面倒になってきました。記事数が増えると、各HTMLの中に同じナビゲーションバーが何度も出てきます。最初はそれでも問題ありません。数ページなら、1つずつ直せます。

しかし、100ページ、200ページと増えてくると話が変わります。カテゴリを追加する。カテゴリ名を変える。表示順を変える。「コラムTop」を「Top」に統一する。検索リンクの表示をそろえる。こうした小さな変更でも、全ページのHTMLを修正する必要が出てきます。

今回やったのは、そこを手作業ではなく、スクリプトで一括更新できるようにしたことです。

何が問題だったのか

Time Columnsは、静的HTMLで運用しています。静的HTMLは軽く、構造が分かりやすく、GitHubとCloudflare Pagesで公開しやすいです。一方で、共通パーツの管理は工夫しないと大変になります。

たとえば、ナビゲーションバーです。各記事のHTMLには、次のようなナビゲーションバーが直接書かれています。

<nav class="nav" aria-label="メインナビゲーション">
  <a href="../../">コラムTop</a>
  <a href="../../chatgpt/">ChatGPT・Codex</a>
  <a href="../../mac/">Mac</a>
  ...
</nav>

この形だと、1ページだけ見れば分かりやすいです。HTMLを開けば、そのページのナビゲーションがそのまま見えます。ただし、サイト全体で見ると問題があります。ナビゲーションバーを変えたいとき、同じようなHTMLを全ページ分直さなければならないからです。

実際に、ページによって「ChatGPT・Codex」とまとまっていたり、「ChatGPT」と「Codex」に分かれていたり、「コラムTop」という表記が残っていたりしました。検索リンクの表記やカテゴリの並びも、少しずつズレていました。これは本文の問題ではなく、共通部品の管理方法の問題です。

何を自動化したのか

今回自動化したのは、全ページのナビゲーションバー更新です。ナビゲーションバーの項目、順番、表示名をスクリプト側にまとめました。そして、そのスクリプトを実行すると、サイト内のHTMLを走査し、各ページの <nav class="nav">...</nav> を同じルールで書き換えるようにしました。

つまり、今後ナビを変更したいときは、各記事HTMLを1枚ずつ直しません。

共通ナビ定義を変更する
↓
同期スクリプトを実行する
↓
全HTMLのナビゲーションバーが更新される
↓
検証してpushする

公開されるHTMLには、これまで通りナビゲーションバーが埋め込まれます。ブラウザで表示するときに、別ファイルを読み込んでいるわけではありません。

今回の仕組みは、表示時に共通ナビを読み込む仕組みではありません。公開前に、共通ナビを各HTMLへ書き込む仕組みです。

なぜJavaScriptで読み込まないのか

ナビゲーションバーを共通化するだけなら、JavaScriptで外部HTMLを読み込む方法もあります。各ページに空のヘッダーだけ置いて、表示時にJavaScriptでナビゲーションバーを差し込む方法です。

しかし、今回はその方法にはしませんでした。理由は、公開HTMLを見た時点でナビゲーションリンクが存在していてほしいからです。検索エンジンやクローラーがページを読んだとき、JavaScript実行後の状態に依存しなくて済みます。

静的HTMLサイトでは、HTMLそのものにリンク構造が入っていることが分かりやすいです。ページ単体を開いても、どこへリンクしているか確認できます。そのため今回は「表示時に読み込む」のではなく、「公開前にHTMLへ焼き込む」方式にしました。

何が変わったのか

今回の修正で、ナビゲーションバーの表記と並びを全ページで統一しました。「コラムTop」は「Top」に統一しました。「ChatGPT・Codex」は、ChatGPTとCodexに分けました。エンジニアリング系のカテゴリは後ろにまとめました。Macカテゴリもその流れの最後に移動しました。検索リンクの表記もそろえました。

ただし、既存ページのURLは変えていません。変えたのは、各ページの中にあるナビゲーションバーです。公開後は、既存記事のURLはそのままで、ページ上部のナビだけ新しい内容になります。

何が自動化されて、何は自動化されていないのか

ここは分けて考える必要があります。今回自動化したのは、全ページのナビゲーションバー更新です。カテゴリ名、表示順、Top表記、検索リンク表記など、ナビゲーションバーの変更は一括で反映できます。

一方で、記事本文、パンくずリスト、関連記事、記事一覧、トップページのカテゴリ枠、sitemap.xmlは別です。これらは今回のスクリプトだけで自動更新されるわけではありません。

対象 自動化されたか
全ページのナビゲーションバー自動化した
ナビのカテゴリ名変更自動化した
ナビの表示順変更自動化した
記事本文対象外
パンくずリスト対象外
関連記事対象外
sitemap.xml対象外
トップページのカテゴリ枠対象外

この範囲をはっきりさせておくと、「全HTMLを自動生成する仕組みにした」という話ではなく、「共通ナビ部分だけを一括更新できるようにした」という話だと分かりやすくなります。

静的HTMLでも共通部品は増えていく

静的HTMLサイトは、最初はとても単純です。HTMLを書いて、CSSを読み込んで、GitHubにpushすれば公開できます。構造も見えやすく、CMSに依存しません。

ただし、記事数が増えると、共通部品が増えていきます。ナビゲーションバー、フッター、関連記事、パンくず、記事一覧、sitemap、検索用データなど、同じ情報を複数箇所で扱うようになります。

このとき、すべてを手作業で直していると、必ずズレます。今回のナビゲーションバーのズレも、その一例です。ページ数が少ないうちは見逃せますが、200ページ規模になると、共通部品は手作業では管理しにくくなります。

まとめ

今回やったのは、静的HTMLサイトの全ページにあるナビゲーションバーを、スクリプトで一括更新できるようにしたことです。

公開HTMLはこれまで通り静的HTMLのままです。ブラウザ表示時に外部ファイルからナビを読み込むわけではありません。共通ナビ定義をもとに、公開前に各HTMLへナビゲーションバーを書き込む方式です。

これにより、次からナビゲーションバーの項目名や並びを変えるときに、全ページを手で直す必要がなくなりました。静的HTMLサイトは軽くて扱いやすい一方で、記事数が増えると共通部品の管理が課題になります。今回の対応は、その中でもまずナビゲーションバーだけを自動化した、小さな運用改善です。