microCMSからGit管理のMarkdownブログへ移行した話
Published on 2025年12月16日
技術はじめに
個人ブログをmicroCMSからGitで管理するMarkdownベースのシステムに移行しました。 この記事では、移行の背景・実装方法・メリットについて紹介します。
なぜ移行したのか?
microCMSの課題
microCMSは素晴らしいHeadless CMSですが、個人開発で使う中でいくつかの課題がありました。
- APIコール数の制限: 無料枠のAPI制限を気にしながらの運用
- 画像の管理: Local環境でtiff画像が表示されないなどの問題
- バージョン管理: 記事の変更履歴がGitで追えない
- オフライン編集: ネットワーク接続が必須
Markdown + Gitのメリット
- 完全無料: 外部サービスへの依存なし
- Git管理: 記事の変更履歴が全て追える
- ローカル編集: VSCodeなど好きなエディタで編集可能
- 高速: ビルド時に静的生成、APIコール不要
システム構成
技術スタック
Next.js 15 + TypeScript
├── gray-matter # frontmatterのパース
├── remark # MarkdownからHTMLへの変換
└── remark-html # HTML出力プラグイン
ディレクトリ構成
project/
├── content/
│ └── blogs/ # MDファイルを配置
│ ├── article-1.md
│ └── article-2.md
├── public/
│ └── images/
│ └── blogs/ # 画像ファイルを配置
└── src/
└── lib/
└── blog/
├── parser.ts # MDパーサー
└── types.ts # 型定義
実装のポイント
1. Markdownファイルの形式
各記事はfrontmatter(YAML形式のメタデータ)+ 本文で構成します。
---
title: "記事タイトル"
publishedAt: "2025-12-16T12:00:00.000Z"
category: "カテゴリ名"
eyecatch: "/images/blogs/sample.png"
---
記事本文をMarkdownで記述...
2. パーサーの実装
gray-matterでfrontmatterをパース、remarkでMarkdownをHTMLに変換します。
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';
export async function getBlogBySlug(slug: string) {
const filePath = path.join(CONTENT_DIR, `${slug}.md`);
const fileContents = fs.readFileSync(filePath, 'utf-8');
// frontmatterと本文を分離
const { data, content } = matter(fileContents);
// MarkdownをHTMLに変換
const processedContent = await remark()
.use(html)
.process(content);
return {
slug,
frontmatter: data,
content: processedContent.toString(),
};
}
3. 記事一覧の取得
ファイルシステムから全記事を取得し、公開日でソートします。
export async function getAllBlogs() {
const files = fs.readdirSync(CONTENT_DIR);
const slugs = files
.filter(file => file.endsWith('.md'))
.map(file => file.replace(/\.md$/, ''));
const blogs = slugs.map(slug => {
const { data } = matter(
fs.readFileSync(path.join(CONTENT_DIR, `${slug}.md`), 'utf-8')
);
return { slug, ...data };
});
// 公開日順でソート(新しい順)
return blogs.sort((a, b) =>
new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime()
);
}
公開フロー
Git + Vercelで自動デプロイ
1. 記事を作成・編集(ローカル)
↓
2. git add & commit
↓
3. git push(mainブランチ)
↓
4. Vercelが自動検知してビルド・デプロイ
↓
5. 公開完了 🎉
エンジニアにとって馴染みのあるGitワークフローで記事を管理できます。
実行フローの比較
microCMS(外部API)の場合
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ ユーザー │ ──▶ │ Vercel │ ──▶ │ microCMS │ ──▶ │ Vercel │
│ リクエスト │ │ サーバー │ │ API │ │ レスポンス │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │
│ APIコール │ JSON返却
│ (ネットワーク経由)│
└────────────────────┘
処理の流れ:
- ユーザーがページにアクセス
- サーバーがmicroCMS APIにリクエスト
- microCMSがJSONを返却
- サーバーでHTMLを生成してレスポンス
Markdown(静的生成)の場合
┌─────────────┐ ┌─────────────┐
│ ユーザー │ ──▶ │ Vercel │
│ リクエスト │ │ 静的HTML │
└─────────────┘ └─────────────┘
│
▼
即座にレスポンス
(ビルド済み)
処理の流れ:
- ユーザーがページにアクセス
- ビルド済みの静的HTMLを即座に返却
フローの違いまとめ
| 項目 | microCMS | Markdown |
|---|---|---|
| リクエスト時のAPI呼び出し | あり | なし |
| 外部サービス依存 | あり | なし |
| ネットワーク遅延 | APIコール分発生 | なし |
| 更新反映 | 即時 | 再ビルド必要 |
外部APIを経由しない分、ネットワーク遅延がなくなりレスポンスが高速化されます。
※ 具体的なレスポンス速度の差については未検証です。時間がある時にLighthouseなどで計測予定。
移行作業
microCMSからのデータ移行
- microCMS APIから全記事を取得
- 各記事をMD形式に変換して保存
- 画像をダウンロードしてpublicに配置
- microCMS関連のコードを削除
まとめ
Before(microCMS)
- API経由でコンテンツ取得
- CMS管理画面で編集
- 画像はCDN配信
After(Git + Markdown)
- ファイルシステムから直接読み込み
- VSCodeで編集、Gitで管理
- 画像はpublicディレクトリに配置
得られたメリット
| 項目 | microCMS | Git + Markdown |
|---|---|---|
| コスト | 無料枠の制限あり | 完全無料 |
| 編集環境 | ブラウザ必須 | 任意のエディタ |
| バージョン管理 | 限定的 | Gitで完全管理 |
| デプロイ | API経由 | 静的生成 |
| 表示速度 | APIレスポンス依存 | 高速(静的) |
個人ブログであれば、このシンプルな構成で十分運用できます。 Headless CMSの便利さを活かしつつ、エンジニアらしいワークフローで記事を管理したい方におすすめです!