0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

静的サイトに管理画面を実装する

0
Last updated at Posted at 2026-08-23

ホームページをもっと作りやすくしたい!!

この投稿では、僕自身がホームページやブログを作りやすく、更新しやすいものとするために、使用した技術や考え方を書いています。

ポートフォリオサイト

静的サイトに管理画面を実装する

静的サイトは速い。軽い。壊れにくい。けれど、ひとつだけ小さな不満がある。

「文章を一文字直すために、コードを開いて、Gitを操作して、再デプロイするのは少し大げさでは?」

この不満を解消するために、静的サイトへ管理画面を足す。するとサイトは、訪問者は、見やすいサイトにアクセスでき、管理者は、コードを書かず、常に最新の情報を簡単に更新することができる。

本稿では、特定のサービス名やフレームワークに依存せず、静的サイトへ安全な管理画面を加えるときの考え方を整理する。

静的サイトは「編集できないサイト」ではない

静的サイトとは、アクセスのたびにサーバーがページを組み立てるのではなく、あらかじめ生成されたHTML、CSS、JavaScript、画像を配信するサイトのことだ。

この仕組みはとてもシンプルだ。公開するだけなら、サーバー側にデータベースも複雑なアプリケーションも必要ない。だから速く、安く、障害にも強い。

一方で、編集機能を考え始めると「静的」と「管理画面」は対立して見える。管理画面は動的、静的サイトは固定。相性が悪そうだ。

しかし実際には、編集する瞬間だけ動的な仕組みを使い、公開時にはまた静的なファイルへ戻せばよい。

公開サイトが毎回データベースに問い合わせる必要はない。編集時だけコンテンツを書き換え、公開時に静的ファイルを作り直す。この分離が、静的サイトに管理画面を持たせる発想の中心になる。

コンテンツを「コードの外」へ出す

最初の一歩は、文章やプロジェクト情報を画面のコードから分離することだ。

たとえば、プロフィール、記事、イベント情報、リンク集を次のようなデータとして保存する。

{
  "title": "静的サイトに管理画面を実装する",
  "summary": "公開の速さを保ちながら、編集しやすい運用をつくる。",
  "tags": ["Static Site", "CMS", "Automation"]
}

保存先はJSONでもMarkdownでもよい。重要なのは、画面の見た目を変えるコードと、伝えたい内容を分けることだ。

この分離には嬉しい副作用がある。

  • 同じデータを一覧・詳細・カード表示で再利用できる
  • 管理画面が編集する対象を明確にできる
  • コンテンツの変更履歴を追いやすい
  • 将来、別のデザインや別の出力形式へ移行しやすい

データは、サイトの「中身」。UIは、それを見せる「器」。両者を分けておくと、サイトは急に長生きする。

管理画面は、Gitへのやさしい入口になる

個人サイトのコンテンツをGitリポジトリで管理すると、変更履歴、差分、復元、レビューという強力な仕組みを自然に使える。

ただし、Gitは万人向けの編集画面ではない。文章を少し直したいだけなのに、ブランチ、コミット、コンフリクトと聞くと、気軽さはどこかへ消えてしまう。

そこで管理画面を用意する。

編集者はフォームで文章を書き、画像を選び、保存ボタンを押す。裏側では、その変更がデータファイルへ反映され、コミットとして記録される。

編集者の体験は「CMS」。運用の実態は「Git」。この二つの間をなめらかにつなぐことが、GitベースCMSの面白さだ。

認証は公開サイトから切り離す

公開ページは誰でも見られる。しかし編集機能まで誰でも使える必要はない。

ここで大切なのは、パスワードやアクセストークンをブラウザのJavaScriptへ埋め込まないことだ。公開された静的ファイルは、原則として誰でも読める。秘密を置く場所ではない。

安全な構成では、認証と権限確認を小さなバックエンドへ切り出す。

この仲介サービスが持つのは、認証に必要な秘密情報と「誰が編集できるか」という判断だけだ。役割を小さく保つほど、攻撃面も運用負担も小さくできる。

公開は「保存」の続きにする

管理画面で保存した後に、別の画面を開いて手動で公開ボタンを押す。これは忘れやすい。

理想は、保存が公開までの入口になることだ。

  1. 編集者が管理画面で保存する
  2. コンテンツの変更が記録される
  3. 自動ビルドが走る
  4. 新しい静的ファイルが公開される

この流れなら、更新作業は「文章を書いて保存する」だけになる。裏側に自動化を置く理由は、作業を派手にするためではない。人間が忘れなくてよい工程を増やすためだ。

外部の発信を集める

自分の発信は、ひとつの場所に収まらないことが多い。技術記事、短いメモ、登壇資料、作品紹介。すべてを手で転記していると、いつか必ず更新漏れが起きる。

そこで、外部サービスの公開APIやRSSフィードを定期的に取得し、サイト用のデータへ変換する。

ここでのコツは、公開ページのブラウザから毎回外部APIを呼ばないことだ。同期処理があらかじめデータを集めておけば、表示は速く、CORSの問題にも悩まされにくい。

外部の発信は散らばっていてもよい。入口だけ、自分のサイトでひとつにすればいい。

Markdownは文章と構造の中間地点

技術記事では、文章だけでなく、表、コード、図が必要になる。

Markdownは、プレーンテキストの書きやすさと、構造化された見た目の間にある。たとえば表は次のように書ける。

| 要素 | 役割 |
| --- | --- |
| コンテンツ | 伝える内容を保持する |
| 管理画面 | 編集の入口になる |
| 自動ビルド | 公開物を再生成する |

さらに、Mermaidのような記法を使えば、図もテキストで管理できる。

図を画像として貼るよりも、文章と同じように差分を確認できるのが嬉しい。設計図まで履歴に残る。

小さく始める

管理画面付きの静的サイトは、最初から万能CMSにする必要はない。

まずは、プロフィールの文章、プロジェクトの追加、記事の下書きなど、更新頻度が高くて手作業が面倒な部分だけを対象にする。それで十分価値がある。

運用していくうちに、「画像もアップロードしたい」「登壇資料をまとめたい」「外部記事も並べたい」と必要なものが見えてくる。そのとき、コンテンツと表示を分けておけば、機能を足しやすい。

静的サイトの強さは、変わらないことではない。変化を小さく、確実に公開できることだ。

実装例:個人ポートフォリオで採用した仕組み

ここからは、考え方を実際の構成へ落とし込むとどうなるかを紹介する。

このポートフォリオは、Next.jsで静的HTMLを生成し、GitHub Pagesで公開している。編集画面にはDecap CMSを使い、GitHub OAuthの認証だけをCloudflare Workersへ任せている。

役割 採用した技術 担当すること
画面 Next.js ページとコンポーネントを静的生成する
公開 GitHub Pages 生成済みのサイトを配信する
管理画面 Decap CMS フォームからコンテンツを編集する
認証 GitHub OAuth 管理者の本人確認をする
認証の仲介 Cloudflare Workers Client Secretを安全に保持する
自動公開 GitHub Actions 保存後にビルド・公開する
記事同期 GitHub Actions ブログ、Qiita、Zennを定期取得する

コンテンツはJSONで持つ

プロフィールやプロジェクト、スライド画像、登壇資料などは、リポジトリ内のcontent/ディレクトリへJSONとして保存している。

content/
├── profile.json        # 名前と自己紹介
├── site.json           # Hero、About、Contact、フッター
├── projects.json       # プロジェクトと技術記事
├── slides.json         # スライドショー画像
├── presentations.json  # 登壇資料
├── blog.json           # 個人ブログから同期した記事
├── qiita.json          # Qiitaから同期した記事
└── zenn.json           # Zennから同期した記事

たとえばプロジェクトは、HomeのPick up、Works一覧、個別の詳細ページで同じprojects.jsonを参照する。編集した内容が複数の画面へ自然に反映されるため、「一覧だけ直したのに詳細が古い」といった事故を防げる。

プロジェクト記事はMarkdownとして書く

各プロジェクトには、概要だけでなく技術記事を持たせている。本文はMarkdownで書き、見出し、リスト、リンク、コードブロック、表を表示できる。Mermaidのコードブロックも図として描画する。

この仕組みによって、作品紹介と技術解説を同じページで扱える。ポートフォリオが「完成品の一覧」だけでなく、考え方や設計の記録にもなる。

管理画面の保存から公開まで

管理画面で保存すると、Decap CMSがGitHubリポジトリのコンテンツファイルを更新する。mainブランチへの変更をGitHub Actionsが検知し、Next.jsを静的ビルドしてGitHub Pagesへ公開する。

管理者に必要なのは、文章を書き、保存することだけだ。ビルドや公開は裏側で進む。

GitHub Pages特有のパス設計

GitHub Pagesでユーザー名.github.io/リポジトリ名/の形式を使う場合、サイトはドメイン直下ではなくリポジトリ名の配下に公開される。このポートフォリオでは/official/配下で公開されるため、Next.jsのbasePathを設定している。

const nextConfig = {
  output: 'export',
  trailingSlash: true,
  basePath: '/official',
}

この設定を忘れると、CSS、JavaScript、画像、アップロードしたPDFが/直下を参照して404になる。静的サイトでは地味だが、とても重要な設定だ。

認証に秘密を置かない

管理画面のGitHubログインでは、OAuth Client Secretを公開サイトに置かない。Cloudflare WorkerのSecretとして保存し、WorkerがGitHubとの認可コード交換とログイン名の確認を担当する。

Workerは「許可されたGitHubユーザーか」を確認してから、管理画面へ認証結果を返す。公開ページは静的なまま、編集だけを安全に限定できる。

外部記事を自動で集める

Resourcesページでは、個人ブログ、Qiita、Zennの記事を定期的に取得している。同期処理はGitHub Actionsで動き、取得結果をJSONへ保存する。

記事を投稿するたびにポートフォリオへ手入力しなくても、時間が経てば一覧へ反映される。自分の発信を集約するための、小さな自動化である。

まとめ

静的サイトと管理画面は、相反するものではない。

編集は動的に、公開は静的に。コンテンツはデータとして、変更は履歴として、公開は自動化として扱う。この役割分担をつくると、個人サイトは単なる作品置き場から、書き続け、育て続けられる場所へ変わる。

そして何より、更新することが少し楽しくなる。

追記

ここでまとめたシステムを使って、個人のポートフォリオとブログを作りました。
ポートフォリオでこのシステムについて、もっと詳しく説明しています。
よければ、読んでみてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?