2025年、AI前提のホームページ作り直し―ObsidianをヘッドレスCMSとした静的サイト(全文検索つき)

## はじめに: AI前提のホームページの前提 ホームページ作成がライフワークといえるほど、この20年以上、自分のホームページを作り直し続けてきました。フルリニューアルだけでも数十回はやってる気がします。 先日「[Raspberry Pi上で動く書籍PDF検索エンジンを作ってDiscordボットとn8nと連携させて

はじめに: AI前提のホームページの前提

ホームページ作成がライフワークといえるほど、この20年以上、自分のホームページを作り直し続けてきました。フルリニューアルだけでも数十回はやってる気がします。

先日「Raspberry Pi上で動く書籍PDF検索エンジンを作ってDiscordボットとn8nと連携させてみた」に書いた通り、Raspberry Piで書籍PDFの全文検索を作りました。その際、ローカルマシン上にためこんだファイルに対してAI技術を用いることの可能性を感じました。その後「メモ管理は Obsidian in Cursor が最強|松濤Vimmer」という記事を見て、やっぱり自分の知的生産に用いるためのデータはローカルにファイルとして持っておくほうがAIの支援を受けやすくて便利だという気持ちが強くなってきました。ローカルでいろんなAIモデルを動かしやすくもなってきましたしね。

Obsidianはこれまで何度か試してみたのですが、日頃メモというものを全然取らないので常用するにいたりませんでした。しかし、そんな自分にも毎日書いているものがあります。それは日記です。日記をどこでどのように書くかというのは、ホームページ作りと同じく長年の課題であり続けてきました。この問題が解決できるならObsidianをちゃんと使っていけそうです。

そこで、ObsidianをヘッドレスCMSとして使うことで、コンテンツはObsidianで管理し、Webサイトとしての表示部分は静的サイトとして実装すればよいのではないかと思いつきました。公開前提の日記や、この記事もそうであるようなブログを書きつつ、プライベートなメモもObsidianのみで管理できたら便利そうです。

このホームページでできること

  • トップページ: プロフィールページの情報をAIエージェントにそれっぽくまとめてもらいました。
  • 日記: 日記を時系列で表示したり、過去の同じ日の日記を振り返ったりできます。
  • ブログ: ストックしたいまとまった考えなどを書きます。
  • アウトプット: note、YouTube、zennなど、様々なプラットフォームでの活動をまとめて表示しています。
  • 個別ページ: いまのところプロフィールページがあります。その後増えるかも。
  • 全文検索: サイト内のコンテンツをキーワードで検索できます。

Webサイトとしては特に変わったことができるわけではないのですが、コンテンツ管理をObsidianで一括してできること、静的サイトでありつつもわりと高速に動く全文検索がついていることあたりが、個人的には気に入っています。

ソースコードはkentaro/kentaro.github.ioに公開しています。Vibe Codingなコードで、これ自体を見てもあまり意味がなさそうですし(そういうコードを書くこと自体はどんどん簡単になっているし)、伝えたいのはアイディアについてなので、以下にポイントを書いていきます。

ObsidianをヘッドレスCMSとして使う

やったこと:

  • ObsidianのデータをGitHubで管理(Gitプラグインを利用)
  • Obsidianのディレクトリ構成を公開用とプライベートなものとに分類
  • 静的サイトビルダーをNext.jsで実装し、上記のリポジトリをsubmoduleとして登録
  • 公開用のディレクトリのみをホームページのコンテンツソースとして利用

Obsidianのディレクトリ構成は、以下のようにしました。特定のフォルダ(ここでは"public"にしてます)に置いたMarkdownファイルが、自動的にホームページのコンテンツになるようにしました。

public/
  journal/YYYY/MM/DD/YYYY年M月D日.md
  blog/YYYY/MM/DD/タイトル.md
  profile.md

...

(publicディレクトリ以外はプライベートなメモ)

Obsidianのようなふだんから使うツール(僕は最近ちゃんと使い始めたのですが)がそのままCMSになるのは便利ですね。

Wasm化されたRDBMSを用いてローカル全文検索する

やったこと:

  • ビルド時にコンテンツから検索用に用いるデータを生成
  • ブラウザ上で動くRDBMSにSQLクエリを実行し、全文検索を実現

これは主に自分自身にとって便利な機能です。たとえばこんなことがありました。ここ数日で花粉症がひどくなってきたので日記を検索したところ、昨年も同じぐらいの頃に同様のことが起こっていたようでした。また、そうなると気分が沈みがちなので、これまでの事例に基づいて、気の持ちようをコントロールすることができます。

ところで、ブラウザ上で完全にローカルで全文検索を実現するというのは、20年前から行われていたことではあります。ここでは、最近の技術を用いて車輪の再発明をしてみました。すなわち、PGliteというPostgreSQLをWebAssembly化したものを使って、ブラウザ上で動く全文検索機能を実装しました。

PGliteのWasmバイナリが2.8MB、記事データが5.8MBほどあるようです。初回のページロード時にデータベースの初期化が走るのですが、いまどきならそんなに問題になるほどでもないかもしれません(検索しようとしたときだけにするような工夫はしたいところです)。

コンテンツ更新をトリガに自動デプロイする

やったこと:

  • コンテンツとコードを別々のGitHubリポジトリで管理
  • コンテンツのリポジトリの更新をトリガーに、ホームページリポジトリのビルドを実行

コンテンツとウェブサイトのコードは、別々のGitHubリポジトリで管理しています。そして、コンテンツを更新したら、自動的にウェブサイトが作り直されて公開されるように、GitHub Actionsを設定しました。どちらも単一のリポジトリで管理することも可能なのですが、Obsidianアプリを開いたときにコードが含まれるのはコンテンツ管理上煩雑なので、分けることにしました。

ホームページのリポジトリは更新があったらGitHub Actionsで自動デプロイするようにしています。さらには、Obsidianで管理しているコンテンツのリポジトリに変更をプッシュすると、GitHub Actionsでホームページのリポジトリのワークフローをトリガするようにしました。そのことで、コンテンツ更新時にホームページのリポジトリ側でもGitHub Actionsが動いて、ビルドとコンテンツ更新ができるようにしました。

コンテンツのリポジトリのワークフローを参考に掲載しておきます(といっても、公開用ディレクトリで更新があったらホームページのワークフローをトリガしてるだけですが)。

name: Trigger Main Repo Workflow

on:
  push:
    branches: [ main ]
    paths:
      - 'public/**'
  workflow_dispatch:

jobs:
  trigger-main-workflow:
    runs-on: ubuntu-latest
    steps:
      - name: Trigger Main Repository Workflow
        run: |
          curl -X POST \
            -H "Accept: application/vnd.github+json" \
            -H "Authorization: Bearer ${{ secrets.HOMEPAGE_REPO_PAT }}" \
            https://api.github.com/repos/kentaro/kentaro.github.io/actions/workflows/deploy.yml/dispatches \
            -d '{"ref":"main"}'

いろんな場所のアウトプットをまとめて表示

やったこと:

  • 複数のプラットフォーム(note、YouTube、zennなど)のRSSフィードを取得
  • ビルド時にフィードを解析し、データを統合
  • 統合したデータを時系列順に並べた静的ページを生成

僕はnoteやYouTube、zennなど、いろんな場所でコンテンツを出しています。以前のホームページでもやっていたのですが、これらを一箇所にまとめて見られるように作ったのがアウトプットページです。自分の活動をふりかえるのに便利です。

やってること自体に特筆すべきことはありません。各サービスのRSSフィードを取得して、時系列順に並べて表示しています。これも、ホームページをビルドするときに自動でデータを取得して、静的なページとして生成しています。

「n年日記」機能で過去のふりかえり

やったこと:

  • 日記コンテンツを日付でインデックス化
  • 同じ日付の過去の日記を並べて表示する「n年日記」ビューを実装

日記を続けていると、「去年の今日は何してたっけ?」と振り返りたくなること、ありますよね。そこで、普通の日記表示に加えて、いわゆる「n年日記」という機能を実装しました。ある日付の日記を年をまたいで見られる機能です。hnsやtDiaryのような、Web日記の創世記からあるCMSが実現していた面白い機能です(「長年日記」をmain trunkにマージ - tDiary.org)。

「あー、去年も同じことで悩んでたな」とか「この頃から考え方が変わってきたんだな」とか、自分の変化を客観的に見ることができて面白いです。Scrapboxで日記を書いていたときは日付のタグを付与することで実現していたのですが、このシステムでは自動的にできるようになりました。

おわりに: 知的生産のベースとしてのホームページへ

このホームページは、Webサイトとしては特にたいしたことをやっているわけではないのですが、AIエージェントの力を借りることによって短期間でこれまで紹介してきたことを実現できました。

そもそもAI前提だとローカルにファイルがある方が取り回しがいいよねということで始めたわけですが、そのあたりはまだまだ全然着手できていません。また、Obsidianでのメモ書きもあまりできていないので、そもそも機能をあまり使えていません。キーワードリンク的な機能なども使っていくと、その辺を記事としてどう扱うかとか、ナレッジベース自体も公開対象にするとか、そういうこともやりたくなりそうです。

Obsidian自体をもっと使いこなせるようになったら、自分の知的生産のベースにしていけるはずなので、今度はそのあたりに取り組んで行きたいですね。