Docs / tech

Contentful に移行したコンテンツを Next.js で表示する

WordPress から Contentful に移行したコンテンツを Next.js で表示するブログのプロジェクトを追加で作成をしました。基本的には WordPress のブログだけであれば、移行をしてしまえばこのプロジェクトで繋がるようになります。

Contentful & Next.js Blog

WordPress からのコンテンツ移行に対応した、Next.js と Contentful を組み合わせたブログのプロジェクトを作成しました。コードは以下の GitHub のリポジトリで公開をしています。

https://github.com/haramizu/contentful-nextjs-blog

利用方法

ローカル開発、またはデプロイする際には、プロジェクトのルートディレクトリに .env ファイルを作成し、以下の値を設定してください。この環境変数に関しては、Vercel などでも同じ値を利用することになります。これのテンプレートとして、.env.example のファイルを準備しています。

CONTENTFUL_SPACE_ID=your_space_id
CONTENTFUL_ACCESS_TOKEN=your_delivery_token
CONTENTFUL_PREVIEW_ACCESS_TOKEN=your_preview_token  # 任意 (プレビュー用)
CONTENTFUL_ENVIRONMENT=master                        # デフォルトは master
NEXT_PUBLIC_SITE_URL=https://your-blog-domain.com    # サイトマップ・RSS・メタデータ用

上記の値を Vercel で展開する場合、production には CONTENTFUL_ACCESS_TOKEN を指定して、プレビューでは CONTENTFUL_PREVIEW_ACCESS_TOKEN が見えるように設定すれば、下書きのコンテンツもプレビューをすることが可能となります。

起動とビルドコマンド

プロジェクトを利用するにあたって、以下の手順を実行してください。

npm install

ローカルでの起動方法はいかのコマンドを実行すれば参照が可能となります。

npm run dev

起動したらカルーセルが表示されて、下のようにブログの記事一覧が表示されています。

Next.js と Contentful を接続

実際にビルドをして、その環境で起動する手順は以下のようになります。

# プロダクション用ビルド
npm run build

# ビルドした成果物で本番環境サーバーを起動
npm run start

プロジェクトの構成

主な機能と特徴

このプロジェクトでは、以下のフレームワークを前提として構築しています。Next.js と組み合わせて使いやすいフレームワークを選択している形です。

  • Next.js 16 (App Router) & React 19 に完全対応。
  • TypeScript による型安全なコンポーネント開発とデータ接続。
  • Tailwind CSS v4 をベースとした美しいダークモードデザインとガラスモルフィズム、スムーズなホバーアニメーション。
  • Embla Carousel & Lucide Icons を活用したレスポンシブなスライド式新着フィーチャーエリア。

ディレクトリ構造

プロジェクトのディレクトリ構造は以下のようになっています。

  • src
    • appNext.js App Router (ルーティング & 画面定義)
      • [year]
        • [month]
          • [day]
            • [slug]
              • TSpage.tsxブログの記事の URL 処理
      • categoriesカテゴリー一覧・カテゴリ別記事
      • tagsタグ一覧・タグ別記事
      • pageページネーション用ページ
      • rss.xml
        • TSroute.tsRSSフィード配信
    • components再利用可能なUIコンポーネント
    • lib
      • TScontentful.tsContentful SDK 設定 & API クエリ関数
    • styles
      • CSSglobals.cssグローバルCSS (Tailwind v4定義)

ブログの構造

WordPress のブログと同じように URL が動くように、以下のような URL のルールとして実装をしています。

  • 元の WordPress 記事のURL構造をそのまま引き継ぐため、/[year]/[month]/[day]/[slug]/ という日付階層つきの動的ルーティングに対応。
  • generateStaticParams によるビルド時事前ビルドと、ISR (Incremental Static Regeneration) による1時間ごとのオンデマンド更新。

後半のオンデマンド更新はあまり必要ないかと思いましたが、ニーズによっては求められるかもしれないので追加した形です。

またサイトの中で利用しているカテゴリとタグに関しての実装は以下のようになっています。

  • カテゴリー一覧とカテゴリー別記事一覧 (/categories/, /categories/[slug]/)。
  • タグ一覧とタグ別記事一覧 (/tags/, /tags/[slug]/)。
  • クエリとルーティングを組み合わせたページネーションコントロール。

一応、slug に関しては日本語にも対応するようにしていますが、その際は Contentful の方にエンコーディング済みの日本語が入っているという実装となっています。この部分が気になる方は、修正はそれほど難しくないかと思います。

SEO & RSS フィードの自動配信

ブログを立ち上げるとなるとやはり気をつけたいのは SEO と RSS です。これに関してはコンテンツの更新に合わせて、きちんと SEO に必要なフィールドが埋まるように、また RSS に関しても自動的に更新をするように実装してあります。

  • 動的 generateMetadata による、記事ごとの適切なメタタグ(OpenGraph / Twitter Card)の自動設定。
  • サイトマップ自動生成 (/sitemap.xml): 記事公開日を最終更新日時(lastModified)にマッピングした高精度のサイトマップ。
  • RSS 2.0 フィード自動生成 (/rss.xml): 最新100件の記事データを配信。

RSS に関しては page.ts ではなく route.tsx (src/app/rss.xml/route.ts) という形で実装しています。

Contentful との連携

このブログを利用するにあたって、Contentful のキーを .env の中に設定をすれば動作するようにしてあります。特に、Delivery API および Preview API の両方に対応させることで、本番環境と下書きプレビュー環境を環境変数で切り替えができるようになっています。

これ以外では、Contentful RichText データの構造を解析し、Next.js <Image> の最適化を含むカスタムレンダリングを実装をしています。これにより、画像に関しては .webp の形式で配信をする形となります。