Next.js + MUI + content-collections で WordPress ブログを再構築した話

Next.js + MUI + content-collections で WordPress ブログを再構築した話

公開日: 12/27/2025

読了目安:

8分

こんにちは、Rafka です。
以前 WordPress で運用していたブログを、Next.js の SSG (Static Site Generation) に移行したので、選定理由など記録しておこうと思います。

はじめに

以前 WordPress で運用してきたブログですが、 カスタマイズの自由度が限られていること、 プラグインの依存関係や更新管理が煩雑であること、 パフォーマンスの最適化が難しいこと、 Markdown でのコンテンツ管理ができないこと、 そしてモダンな開発体験を得られないことなど、 さまざまな課題を感じていました。 これらの課題を解決するため、 モダンなアーキテクチャでのブログ再構築を決断しました。

技術スタックの選定

Next.js を選んだ理由

Next.js は、ビルド時に静的 HTML を生成する SSG により、 HTML + CSS + JS の構成での Web Site の構築が可能です。
仕事で触っていることもあり、React を使うためのハードルは全く無く、 更に Wordpress の時に悩ましかった、 PHP の Version や WordPress の Version の更新についても気にする必要が無くなるため、 Next.js の採用に踏み切りました。
更に TypeScript のフルサポートや、 Next.js 16 からデフォルトとなった Turbopack によるさらなる高速化など、 開発体験の良さも選定理由の一つです。

Material UI を選んだ理由

UI ライブラリには Material UI v7 を採用しました。
そもそも私が、Google の Material Design が好きというのが大きな理由ですが、 Web Site を構築する為に必要となるコンポーネントが一通り揃っており、 それぞれのコンポーネントについてのカスタマイズ性も十分な点が採用理由です。
公式のガイドラインに従って実装するだけで、 Material Design に基づいた統一的なスタイルを採用でき、 Dark Mode 対応やコントラストを確保した色の切り替え設定なども行いやすい部分も、 最高です。

content-collections を選んだ理由

コンテンツ管理には content-collections を採用しました。
Zod スキーマによる厳密な型定義で、 ビルド時に型エラーを検出でき、 TypeScript との統合が完璧な型安全なコンテンツ管理を実現できます。
Markdown と YAML の両方をサポートし、 frontmatter でメタデータを管理でき、 カスタム変換処理が簡単に実装できる柔軟なデータソースも特徴です。
ビルドプロセスにシームレスに統合され、 Fast Refresh に対応し、 高速なコンテンツの再構築が可能な Next.js との統合も優れています。
さらに MDX のサポート、 rehype/remark プラグインによる拡張、 カスタムコンポーネントの埋め込みが容易な拡張性の高さも採用理由です。

スキーマ定義

例えば、content-collections.ts でブログ記事のスキーマを以下のように定義してみます。
const posts = defineCollection({
  directory: 'src/posts',
  include: '**/*.{md,mdx}',
  name: 'posts',
  schema: z.object({
    title: z.string(),
    date: z.string(),
    category: z.string(),
    tags: z.array(z.string()).optional(),
    summary: z.string().optional(),
    header: z
      .object({
        src: z.string(),
        width: z.number().optional(),
        height: z.number().optional(),
      })
      .or(z.string())
      .optional(),
    // ... その他のフィールド
  }),
  transform: async (document, context) => {
    // MDX へのコンパイルやメタデータの生成
  },
});
この定義により、 ビルド時に src/posts 以下に置いてある全ての Markdown や MDX ファイルに対して、 frontmatter に書かれている内容のスキャンが行われ、 定義に合わないものについてはその時点で検出できます。

自動生成機能の実装

content-collections の transform 関数を活用して、 以下の様なさまざまな機能を自動生成しています。
  • 読了時間の計算
  • 目次の自動生成
  • LaTeX 記法での数式表示
  • 外部 Link のリッチな表示
例えば、読了時間の計算のコードは以下の通りで、 これを先程の defineCollection で定義していた transform から呼び出しています。
const calculateReadingTime = (content: string): number => {
  const CHARS_PER_MINUTE = 500;
  const charCount = content.length;
  const minutes = Math.ceil(charCount / CHARS_PER_MINUTE);
  return Math.max(1, minutes);
};

今回の移行で良くなった事

パフォーマンスと移行しやすさの向上

移行により、 PHP + WordPress から HTML + CSS + Javascript の構成に変わったので、 初回レンダリングやサイト内の遷移が気持ち早くなったように思います。
構成も、Apache や Nginx と、シンプルな HTML + CSS + Javascript 構成なので、 例えばサーバを引っ越すなどの場合でも、 引っ越し先に Web Server を立てて、後はファイルをコピーすれば引っ越しが完了するので、 非常にシンプルなフローで実現できるようになりました。
Apache や Nginx の Version も上げやすいですね👍

コンテンツ管理の効率化

記事を Markdown で執筆できるようになったので、 WordPress の編集画面と比較して "何" を "どの様に" 配置するか に集中できる様になったと思います。
content-collections の機能によって、 React のホットリロードで即座に見た目も確認できるため、 そこも良いですね。
作成した記事は、GitHub Actions でサーバに自動デプロイされるので、 記事の執筆も通常の開発サイクルの延長でできる点も良く感じています。

まとめ

WordPress から Next.js + MUI + content-collections への移行は、 学習コストも無く、大きなメリットを受けられました。
技術的には、パフォーマンスの大幅な向上、 型安全性による開発効率の改善、 簡素なアーキテクチャによる拡張性と可搬性が得られたと思います。
運用面では、 Markdown による簡素なコンテンツ管理、 GitHub Actions による更新の自動化が実現できました。
自分で自由に細かいところまでカスタマイズが効く様にできたので、 今後も継続的に改善を続けながら、 得られた知見を発信していきたいと思います。

この記事が、同様の移行を検討している方の参考になれば幸いです。 質問やフィードバックがあれば、お気軽にコメントや SNS でお知らせください!

Rafka

Rafka

Software Engineer

Rafka って言います。品川でソフトウェアエンジニアやってます。

Limbus Company の攻略と感想、中央競馬 G1 レースの予想、参加したイベントの感想などを書いています。

大学では計算論的神経科学や高性能計算を研究していたので、数値シミュレーションの解説も書いています。

Ace Combat 8 を買いました!シリーズファンなのでめっちゃ楽しんでいます!

関連記事