microCMSとNext.jsを使用して、この自作ブログアプリを開発しました。
CMSとは?
CMSはContents Management Systemの略で、ブログやお知らせなどのコンテンツを管理・更新できるシステムです。
microCMSについて
microCMSは、日本初の「ヘッドレスCMS」で直観的に入稿できるシステムによってあらゆる編集者にもわかりやすく、様々な要件にも対応できます。
(ヘッドレスCMSとは、表示部分のフロントを持たず、API経由で提供するCMSです)
つまり、microCMSは、「データの中身だけ管理して、表示は自分で自由に作れるCMS」です!
実装手順
microCMSの設定
microCMS(microCMS|APIベースの日本製ヘッドレスCMS)から、登録・ログインを完了しておきます。
.png)
ここから、「一から作成する」を選びます。
「サービス名」と「サービスID」を好きなように入力します。
.png)
次に、APIの作成をします。
私は、今回簡単なブログサイトを作るだけだったので、画面内のテンプレートの「ブログ」を使用しました。
「自分で決める」を選べば、ブログ内に含めたいデータを自分で決めることができます。
.png)
このような画面が開き、1件自動的にテンプレートの投稿が公開になっています。
右上の追加ボタンから、投稿の追加を行います。
.png)
とりあえず、何でもいいので、「タイトル」・「内容」・「サムネイル画像」をいれておきます。
Next.jsプロジェクトの作成
npx create-next-app project-name
cd project-name
code .
create-next-appを使って、プロジェクトを作成し、そのプロジェクトのディレクトリに移動しコーディングを開始します。
npm run dev
これで開発サーバーを立ち上げます。
.env.localファイルの作成
microCMSからブログ内のデータをリクエストするのにAPIキーを使用することで特定のデータを取得します。
しかし、このAPIキーは、セキュリティの観点から公開するのは危険なため、envファイルに書くことでGitHub上にpushしても.gitignoreファイルによってenvファイルは公開されないのでAPIキーを保護することができます。
MICROCMS_API_KEY=xxxxxxxxxx
MICROCMS_SERVICE_DOMAIN=xxxxxxxxxx
.env.localファイル内にAPIキーとService Domainをいれておきます。
.png)
※APIキーは、microCMSの画面内の「権限管理」のところから確認できます。
※Service Domainは、microCMSの画面のURLを確認し、https://この部分.microcms.ioになります。
microcms-js-sdkのインストール
npm install microcms-js-sdk
これで、microcms-js-sdkをインストールしておきます。
libs/microcms.tsを作成
libs/microcms.tsを作成し、その中に以下を書きます。
// libs/microcms.ts
import { createClient } from 'microcms-js-sdk';
// 環境変数にMICROCMS_SERVICE_DOMAINが設定されていない場合はエラーを投げる
if (!process.env.MICROCMS_SERVICE_DOMAIN) {
throw new Error('MICROCMS_SERVICE_DOMAIN is required');
}
// 環境変数にMICROCMS_API_KEYが設定されていない場合はエラーを投げる
if (!process.env.MICROCMS_API_KEY) {
throw new Error('MICROCMS_API_KEY is required');
}
// Client SDKの初期化を行う
export const client = createClient({
serviceDomain: process.env.MICROCMS_SERVICE_DOMAIN,
apiKey: process.env.MICROCMS_API_KEY,
});
これで、envファイルで設定した環境変数を参照するように設定します。
ブログを表示する
ブロブの一覧ページ、ブログの詳細ページを表示するなら、基本的にSSG+ISRでの表示がいいと思います。
- SSG(Static Site Generation)→ビルド時にHTMLを生成しておき表示するため、表示速度が速くSEOにも強い。
- ISR(Incremental Static Regeneration)→SSGに再生成(再ビルド)を組み合わせた仕組み。指定時間で新しいHTMLを再生成する。
ブログ一覧を表示する
// ブログ記事の型定義
type Props = {
id: string;
title: string;
};
// microCMSからブログ記事を取得
async function getBlogPosts(): Promise<Props[]> {
const data = await client.getList({
endpoint: 'blog', // 'blog'はmicroCMSのエンドポイント名
queries: {
fields: 'id,title', // idとtitleを取得
limit: 5, // 最新の5件を取得
},
});
return data.contents;
}
getBlogPosts()でmicroCMSからブログのデータを取得します。
export default async function Home() {
const posts = await getBlogPosts();
return (
<main>
<h1>ブログ記事一覧</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link href={`/blog/${post.id}`}> {/* 記事へのリンクを生成 */}
{post.title} {/* タイトルを表示 */}
</Link>
</li>
))}
</ul>
</main>
);
}
Home()内で、getBlogPosts()を動かし、そこから取得したデータをpostsに入れ、return内でmap関数を使って全投稿のデータを表示します。
//IRS設定
export const revalidate = 300;
これで、IRSを設定します。
SSRに関して、Next.jsのApp RouterのサーバーコンポーネントであればデフォルトでSSRになっています。
ブログの詳細ページを表示する
app/blog/[id]/page.tsxを作成します。
- 動的ルーティングを行うために、全投稿のIDを取得します。
export async function generateStaticParams() {
const data = await client.getList<Props>({
endpoint: 'blog', // 'blog'はmicroCMSのエンドポイント名
})
return data.contents.map((blog) => ({
params: {id: blog.id}
}))
}
- BlogDetail()の中で実際のURL(ID)を取得する
//PagePropsの型定義
type PageProps = {
params: Promise<{id: string}>
}
export default async function BlogDetail({params}: PageProps) {
const {id} = await params;
- そのIDを基に、そのIDのデータをmicroCMSから取得する。
//idを基にデータを取得する関数を作る
async function getBlogDetail(id: string): Promise<Props | null> {
const data = await client.get<Props>({
endpoint: 'blog', // 'blog'はmicroCMSのエンドポイント名
contentId: id,
}).catch(() => null)
return data
}
//実際にidを受け取ってそのidのデータを取得・表示する
export default async function BlogDetail({params}: PageProps) {
const {id} = await params;
const data = await getBlogDetail(id);
return (
<main>
<h1>{data.title}</h1>
<div dangerouslySetInnerHTML={{__html: data.content}} />
</main>
);
}
- 一覧ページと同様にISRの設定をする
//IRS設定
export const revalidate = 300;
ビルドする
npm run build
これでビルドします。
まとめ
大まかに、このような流れでこのmicroCMS×Next.jsの自作ブログサイトを構築しました。
実際にVercelなどでデプロイする際は、環境変数を入力することでデプロイできます。
参考にしたサイト: