Back to Portfolio

Case Study · 05 · Live

Seu Days

雑多な備忘録の墓場 — Astro × Cloudflare Pages で運用する個人ブログ

Problem

既製のブログは便利で、同時に窮屈だった。

既製のブログサービスはどれも立ち上げが速くて便利だけれど、手軽さと引き換えに必ず何かを諦めさせてくる。URL 構造 / レイアウト / タイポグラフィ の主権を自分の手元に置けないと、「読み物としての体験」を磨こうとした瞬間に壁にぶつかる。

同時に、日々のメモを「書くたびに調べ直す」ことを減らしたかった。

個人の備忘録として フォーマットを気にせず気軽に流し込める場 — その一点だけが満たされた静的ブログが欲しかった。

Approach

Astro Islands × 内製の裏方一式。

オープンソーステーマ Fuwari を fork し、日本語タイポグラフィ (BudouX + Noto Sans JP) を前提に作り直すところから始めた。記事ページは 99% 静的、インタラクティブな要素だけを Svelte 5 の island として埋め込む構成で、初回 JS バンドルを極力ゼロに近づけている。

全文検索は Pagefind。ビルド時にインデックスを生成し、クライアント JS だけで検索が完結するのでホスティング側に一切依存しない。OG 画像は Satori + @resvg/resvg-js で記事ごとにビルド時生成。Cloudflare Workers は Native モジュールを動かせないので、adapter: cloudflare({ prerenderEnvironment: "node" })vite.ssr.external を組み合わせ、プリレンダー時だけ Node ランタイムに切り替えて逃がしている。

執筆から公開までのフローは GitHub Actions に全部寄せたreviewed: truepublished <= today を満たす draft を毎日 JST 18:00 に scripts/publish-scheduled.js が抽出し、draft: false 化 → develop コミット → main へ自動 PR 作成。「書く」と「出す」をフラグひとつで分離できる運用に落ち着いた。

執筆規約は CLAUDE.md に形式知化.claude/agents に post-planner / seo-reviewer、.claude/skills に frontmatter-check / new-post / tip-list-format を置き、「企画 → 下書き → SEO レビュー → 予約公開」をエージェントに渡せる形にしている。

Astro 6 + Svelte 5 Islands

記事ページは実質ゼロ JS。

必要な箇所だけ Svelte 5 の island として動的化する。

Pagefind 全文検索

pnpm build で自動インデックス。

クライアント JS だけで全文検索が完結し、サーバー不要。

記事ごとの OG 画像動的生成

Satori + satori-html + @resvg/resvg-js でビルド時にOG画像を生成。

フォールバックも自動。

カスタム Markdown ディレクティブ

:::photo / :::photosm / :::github / :::googlemap / :::note を rehype-components で実装。PC / スマホ最適なフレーム付きスクショに変換。

予約公開ワークフロー

reviewed: true の draft を毎日 JST 18:00 に GitHub Actions が自動公開 → develop → main PR。

Claude Code 統合

.claude/agents.claude/skills で企画 → 下書き → SEO レビューをエージェントに渡せる執筆フロー。

Seu Days のデスクトップホーム画面。左サイドバーに手描き風プロフィール、カテゴリ、タグ。中央に記事一覧。
Home3 カラムのサイドバー付き記事一覧
Seu Days のデスクトップ記事ページ「SEO と AEO の違い」。右側に目次 TOC を表示。
Article右サイドバーの TOC で現在地を可視化
Seu Days のモバイルホーム画面。カード型の記事一覧を縦スクロールで表示。
Mobile Homeモバイルファーストのカードレイアウト
Seu Days のモバイル記事ページ「SEO と AEO の違い」。BudouX による日本語の自然な改行で読みやすく整形。
Mobile ArticleBudouX + Noto Sans JP の日本語組版
Framework
Astro 6 (SSG) + Svelte 5 (islands)
Styling
Tailwind CSS 3 + Stylus + @tailwindcss/typography
Markdown
remark-directive / rehype-components / Expressive Code / KaTeX / Mermaid
Search
Pagefind 1.x
OG images
Satori + satori-html + @resvg/resvg-js + sharp
Hosting
Cloudflare Pages (@astrojs/cloudflare, prerenderEnvironment: node)
CI
GitHub Actions (build.yml / biome.yml / publish-scheduled.yml)
Lint / Format
Biome 2
Package manager
pnpm (preinstall で強制)
AI 協業
Claude Code (.claude/agents, .claude/commands, .claude/skills)

Result

書くたび、仕組みではなく言葉に集中できる。

2025 年末から継続運用中。Fuwari テンプレートの fork → 日本語化 → 独自ディレクティブ追加 → CI 整備という段階的進化を経て、2026-04 時点で約 15 本の記事を公開している。Lighthouse は Performance / SEO / Best Practices / Accessibility すべて 90+ を維持目標に。

ライセンスは、コードが MIT 相当 (Fuwari ベース)、記事本文は CC BY-NC-SA 4.0

最新版は blog.c12o.net で公開中。

Learnings

作ってみて分かったこと。

執筆規約を CLAUDE.md に書き出すと、AI 執筆の品質が安定する

一人称の統一・章立て・見出しの付け方といった暗黙のルールを明文化しておくだけで、Claude Code が下書きを書く際のブレが激減した。

規約は "書く人を増やす" ためだけのものではなく、"自分を含めた執筆者全員を揃える" ための装置だった。

個人ブログでも CI / 自動化への投資は割に合う

lint / build / 予約公開 / PR 作成までを GitHub Actions に寄せると、運用フェーズの認知負荷が段違いに下がる。

個人運用で一番大事なのは「機能」ではなく「継続できる仕組み」だと実感した。

静的サイトでも "動的に見える機能" はビルド時で足りる

OG 画像生成・全文検索・Mermaid 図・KaTeX まで、全部ビルド時に解決すれば配信はただの静的 HTML で済む。

読者から見える体験は動的なのに、ランタイムでは何も動いていないという気持ちよさ。

Workers ランタイムの Native モジュール問題は "環境を分ける" が正解

@resvg/resvg-js のような Native 依存は Workers で動かせない。

prerenderEnvironment: "node" で SSG 時だけ Node に逃がす構成に切り替えてからは、画像生成系の選択肢が一気に広がった。

「どこで動かすか」を環境ごとに分けられるのは Astro アダプタの思わぬ強みだった。

日本語組版は BudouX + Noto Sans JP の二枚看板

日本語の改行・等幅崩れは、BudouX による文節分割と @fontsource/noto-sans-jp の自前ホストで解決した。

英語圏テンプレートを日本語化するうえで最初に投資すべき場所はここだと分かった。

"書く" と "出す" をフラグで分離する

reviewed: true という 1 フラグを入れるだけで、下書きをレビュー後に予約公開する運用が成立した。

SaaS ブログで "下書き管理" に使っていた気力を、そのまま本文に注げるようになったのが一番の効用。