🌸

1時間でJamstackなブログを作って公開しよう(Next.js / microCMS / Cloudflare Pages)

2024/02/14に公開

作るもの

本記事では、Next.js、microCMS、Cloudflare Pagesを組み合わせて、静的サイト生成(SSG)によるブログを作成する方法をステップバイステップで説明します。
「(維持費が)安い・(ページ表示が)速い・(管理が)楽ちん」なブログを作りたいエンジニアにおすすめです。

所要時間: 1時間
料金: 0円

今回は、GitHubへのプッシュをトリガーとしてサイトを自動的にビルド・デプロイする環境、さらにCMSでの記事公開が即座にブログに反映される環境を構築します。

Cloudflare Pagesは、静的ファイルのホスティング機能を提供するプラットフォームです。
無料で使え、さらにCloudflareのCDNを通じて配信されるため、高速なページ表示が期待できます。

microCMSは、APIを介してコンテンツを管理・取得できる日本製のヘッドレスCMSです。
ユーザーフレンドリーなUIを用いてブログ記事を簡単に公開・編集することができます。

各サービスやコードの詳細説明は省略します。

必要な環境

  • Node.js 18.7以上

手順

Next.jsプロジェクトの作成

Cloudflareが提供しているcreate-cloudflare CLIを使うと、簡単にCloudflareへのデプロイ設定が整ったプロジェクトを作成することができます。
tech-blogという名前でNext.jsプロジェクトを作成します。

npm create cloudflare@latest tech-blog -- --framework=next

重要 オプションDo you want to deploy your application?noと答えてください。ほかはデフォルトでOKです(お好みで変更してください)。

Do you want to deploy your application?
> no

Githubリポジトリの作成、プッシュ

Githubにtech-blogリポジトリを作成します。
Next.jsプロジェクトをプッシュしておきます。

git remote add origin git@github.com:アカウント名/tech-blog.git
git push origin main

Cloudflareアカウントの取得

Cloudflareにサインアップします。
すでにアカウントを取得している人はログインしてください。
https://dash.cloudflare.com/sign-up

Cloudflareアプリケーションの作成

※日本語設定の人は適宜読み替えてください

左メニューの「Workers & Pages」を選択します。
ページ上部の「Create Application」を選択します。

「Pages」タブを選択し、「Connect To Git」を押します。

自分のGitアカウントに接続します。

Cloudflareと連携するためにリポジトリのアクセスを許可します。
「If you repository ~」のリンクをクリックして、さきほど作成したtech-blogリポジトリをひもづけします。

設定を進めます。プロジェクト名はtech-blog、ブランチはmain、フレームワークプリセットはNext.jsを選択します。
※ビルドコマンド、ビルド出力ディレクトリはNext.jsを選択したときのデフォルトのまま


「保存してデプロイする」を選択すると、初回デプロイが開始されます。

Cloudflare Pagesでは、デフォルトでxxx.pages.devというドメインが割り当てられており、公開URLでアクセスできるようになっています。

初回デプロイ時は、画面にNode.JS Compatibility Errorというエラーが出ていて、上手くページを確認することはできません。

Cloudflare Pagesの設定変更

ページが正しく表示されるように設定を変更します。

Cloudflare Pagesのダッシュボードから設定を開きます。

Functions > Compability Flag (互換性フラグ)に、nodejs_compatを追加します。

ダッシュボードのデプロイ一覧に戻り、前回の履歴のメニューから「デプロイを再試行」を選択します。

デプロイが完了したら、xxx.pages.devからページがうまく表示されていることを確認できます。

nodejs_compatについて補足

Node.JS Compatibility Errorというエラーは、プロジェクトが要求するNode.jsのバージョンとCloudflare PagesのデフォルトのNode.jsのバージョンとの間に互換性がない場合に起こります。

nodejs_compatフラグは、Cloudflare PagesがプロジェクトのNode.jsバージョン要求に合わせて動作するようにするものです。

Next.jsのページを編集する

ページを編集、更新し、Githubにプッシュすると自動でデプロイが走ることを確認してみます。

下記は極限までシンプルにした例です。お好みに編集してください。

global.css
@tailwind base;
@tailwind components;
@tailwind utilities;
layout.ts
import type { Metadata } from "next";
import "./globals.css";

export const metadata: Metadata = {
  title: "Tech Blog",
  description: "I share insights on the technology, design, and culture.",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <div className="max-w-5xl mx-auto p-8">{children}</div>
      </body>
    </html>
  );
}
page.tsx
export default function Home() {
  return (
    <main>
      <h1 className="text-2xl font-bold my-4">ブログ</h1>
    </main>
  );
}

コミットしてmainブランチにプッシュします。
Cloudflare Pagesで自動でデプロイが走り、コードの変更がサイトに反映されたことを確認します。

microCMSのアカウント作成

ブログの記事のAPIをmicroCMSで作成します。

まず、microCMSでアカウントを作成します。

https://app.microcms.io/signup

microCMSでAPIを作成

サインアップしたらサービスを作成します。
「一から作成する」を選択します。

サービス名はブログ、サービスIDはデフォルトで入力されている文字列のままにします。

ブログ記事のAPIを作成します。
microCMSでは、APIを3つまで無料で作成することができます。
テンプレートの「ブログ」を選択します。

APIのエンドポイントとして、「ブログ」と「カテゴリ」の2つが作成されます。
ブログにはサンプル記事が1つ作成された状態になっています。

左メニューの権限管理 > 1個のAPIキー からAPIキーを確認することができます。

CloudflareにmicroCMSの環境変数を登録する

Cloudflare PagesのダッシュボードからSettings > Environment & Variablesを開きます。

Productionに、SERVICE_DOMAINAPI_KEYの2つの環境変数を設定します。
それぞれmicroCMSのサービスドメイン(サービスID)とAPIキーです。

Saveを押して保存します。

Next.jsからmicroCMSのAPIを利用する

ブログページに、microCMSの記事を表示できるようにしましょう。

Next.jsプロジェクトにmicroCMSのSDKをインストールします。

npm install microcms-js-sdk

プロジェクトのルート直下に.env.localファイルを作成します。
microCMSのサービスドメイン(サービスID)、APIキーを記述します。

.env.local
SERVICE_DOMAIN=microCMSのサービスドメイン
API_KEY=microCMSのAPIキー

src/libs/client.tsを作成します。

client.ts
import { createClient } from "microcms-js-sdk";

export const client = createClient({
  serviceDomain: process.env.SERVICE_DOMAIN ?? "",
  apiKey: process.env.API_KEY ?? "",
});

データ型の定義もしておきます。
src/app/types.d.tsを作成します。

types.d.ts
interface Blog {
  id: string;
  title: string;
  content: string;
  eyecatch: {
    url: string;
    height: number;
    width: number;
  };
  category: Category;
  createdAt: string;
  updatedAt: string;
  publishedAt: string;
}

interface Category {
  id: string;
  name: string;
}

src/app/pages.tsxを編集し、ブログタイトルの一覧を表示します。

src/app/pages.tsx
import { client } from "@/libs/client";
import Link from "next/link";

export default async function Home() {
  const blogs: Blog[] = await client
    .get({ endpoint: "blogs" })
    .then((res) => res.contents);

  return (
    <main>
      <h1 className="text-2xl font-bold my-4">ブログ</h1>
      <ul>
        {blogs.map((blog) => (
          <li key={blog.id}>
            <Link href={`/blog/${blog.id}`}>{blog.title}</Link>
          </li>
        ))}
      </ul>
    </main>
  );
}

ブログの詳細ページも作成しましょう。
src/app/blogs/[id]/page.tsxを作成します。
ファイル先頭で必ずruntimeをedgeに指定してください。

src/app/blogs/[id]/page.tsx
export const runtime = "edge";

import { client } from "@/libs/client";
import Link from "next/link";

export default async function BlogPage({
  params: { id },
}: Readonly<{
  params: {
    id: string;
  };
}>) {
  const blog: Blog = await client.get({ endpoint: "blogs", contentId: id })

  return (
    <main>
      <Link href="/">戻る</Link>
      <h1 className="text-2xl font-bold my-4">{blog.title}</h1>
      <div
        className="my-4"
        dangerouslySetInnerHTML={{
          __html: blog.content,
        }}
      />
    </main>
  );
}

npm run buildを試しビルドが通ったら、リモートリポジトリにプッシュします。

Cloudflare Pagesでデプロイが成功すれば、ブログ一覧ページと詳細ページが表示されていることを確認できます。

一覧ページ(https://xxx.pages.dev

詳細ページ(https://xxx.pages.dev/blogs/id)

ここまででブログを公開する目的は達成しました。
このあとはWebhookを作成し、記事をmicroCMSで公開したら、Cloudflare Pagesで自動でデプロイが走ってサイトが更新されるようにします。

Webhookの作成

Cloudflare Pages側でWebhookを作成します。
ダッシュボードからSettings > Builds & deploymentsを開きます。
Deploy hooksで「Add deploy hook」を選択します。

名前はmicroCMS-blog、ブランチはmainにします。

作成後に表示されるWebhook URLをコピーしておきます。

次に、microCMS側の設定に移ります。

「ブログ」APIの設定画面からWebhookを選択します。
「追加」を押して、「Cloudflare Pages」を選択します。

Webhookの識別名はcloudflare-pages、URLには先ほどコピーしたWebhook URLを貼り付けます。
通知タイミングはデフォルトのチェック状態にしておきます。
「設定する」を押して、連携を完了します。

試しにブログ記事を一つ作成してみます。
タイトル、内容を記入したら「公開」を押して記事を公開します。

Cloudflare Pages側で自動でデプロイが走り、記事が公開されました。

これでブログの完成です!

このあと

あとは自由にカスタマイズしてください。

  • ブログのデザインを整える
  • カテゴリごとにフィルタリングする機能をつける
  • 独自ドメインを取得して割り当てる(Cloudflareでは簡単にドメインを取得できます)

etc.

Discussion