Next.js App router + microCMSで画像を含んだコンテンツを表示する
はじめに
Next.js App router + microCMSで次のように画像を含んだコンテンツを表示する方法を記述しております。
参考にさせていただきました。
microCMSとは
microCMSは日本発のヘッドレスCMS(Content Management System、コンテンツ管理システム)です。
microCMSはAPIベースで動作し、ウェブサイトやアプリケーションに動的コンテンツを提供しています。
ヘッドレスCMS
フロントエンドの表示部分(ヘッド)とバックエンドのデータ管理部分が分離されているシステムのことを指します。
APIの作成
一から作成する
サービス名とサービスIDを入力して、サービスを作成する
サービスにアクセスする
自分で決める
入力して次へ
リスト形式
を選択し、次へ
APIスキーマを作成したら、作成
を押してください。
コンテンツの作成
追加
を押してください。
OK
を選択してください。
SDKのインストール
microCMSのAPIを簡単に利用するためのSDK((Software Development Kit))をインストールしてください。
npm install microcms-js-sdk
プロジェクトのルートディレクトリlibs/client.js
を作成してください。
mkdir libs && touch libs/client.js
microCMS APIとの接続するための設定を記述してください。
import { createClient } from 'microcms-js-sdk';
export const client = createClient({
serviceDomain: process.env.NEXT_PUBLIC_SERVICE_DOMAIN_ID || '',
apiKey: process.env.NEXT_PUBLIC_API_KEY || '',
});
下記の黒枠の部分です。
APIルートの作成
X-Microcms-Api-Key
でAPIキーが確認できてしまうので、APIのルートを作成してクライアントサイドではなく、サーバーサイドでリクエストを送るようにします。
route.ts
ファイルを作成してください。
mkdir -p src/app/api/microCMS && touch src/app/api/microCMS/route.ts
詳しくはこちらの記事を確認してください。
import { NextResponse } from 'next/server';
import { client } from '../../../../libs/client';
export async function GET() {
try {
const res = await client.get({
endpoint: process.env.END_POINT || '',
});
return NextResponse.json(res, { status: 200 });
} catch (error) {
throw error;
}
}
microCMSのAPIからデータを取得する
'use client';
import axios from 'axios';
import Image from 'next/image';
import { useEffect, useState } from 'react';
interface Image {
createdAt: string;
id: string;
image: {
url: string;
height: number;
width: number;
};
publishedAt: string;
revisedAt: string;
text: string;
title: string;
updatedAt: string;
}
export default function Home() {
const [data, setData] = useState<Image[]>([]);
useEffect(() => {
const getData = async () => {
try {
const response = await axios.get('/api/microCMS');
setData(response.data.contents);
} catch (error) {
if (axios.isAxiosError(error)) {
console.error('Axiosのエラーが発生しました:', error);
} else {
console.error('Axios以外のエラーが発生しました:', error);
}
}
};
getData();
}, []);
return (
<main>
{data.length > 0 && (
<main>
<div className='flex'>
{data.map((item, index) => (
<div key={index} className='flex-grow'>
<h3>{item.title}</h3>
<Image
src={item.image.url}
alt={item.title}
width={200}
height={100}
priority
/>
<p>{item.text}</p>
</div>
))}
</div>
</main>
)}
</main>
);
}
環境変数の設定
.envファイルを作成してください。
touch .env
NEXT_PUBLIC_SERVICE_DOMAIN_ID='<サービスID>'
NEXT_PUBLIC_API_KEY='<APIキー>'
END_POINT='<エンドポイント>'
APIキーは、権限管理から確認できます。
URLパターンの指定
このままでは画像が表示されないと思います。
下記のように指定されたパターンにマッチする画像URLから画像を取得して最適化を行うことを許可してください。
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.microcms-assets.io',
},
],
},
};
export default nextConfig;
remotePatterns
については下記を参考にしてください。
ローカルの開発環境でコンテンツの変更が反映されない
下記コマンドで.next/cache
ディレクトリ内のキャッシュが削除すると反映されました。
rm -rf .next/cache
毎回手動でキャッシュを削除するのは大変なので、コマンドを修正しました。
"dev": "rm -rf .next/cache && next dev",
コンテンツの変更が反映されない問題について、.next/cache
ディレクトリ内のキャッシュが削除する以外にわからなかったので、キャッシュを無効にする方法などご存知の方はコメントで教えていただけると助かります。
またクライアントサイドのみでデータを取得するようにしているものを、ビルドしてS3にアップロードしたところ問題なく、コンテンツの変更は反映されていました。
終わりに
何かありましたらお気軽にコメント等いただけると助かります。
ここまでお読みいただきありがとうございます🎉
Discussion