この記事は techtekt アドベントカレンダー2023 の22日目の記事です🎁
こんにちは、エンジニアの青木です。
10/18 に技育CAMPアカデミアで登壇した際にハンズオンを実施したのですが、この記事ではその内容について簡略化して紹介したいと思います。
はじめに
バックエンドとしてmicroCMSを使い、Next.jsアプリケーションを開発するのがハンズオンの中身になります。
仕事でヘッドレスCMSについて触れる機会があり、非常に使いやすいと感じたこと、またNext.jsなどのWebアプリケーションフレームワークと組み合わせやすいと感じたことから、このハンズオンを考えました。
はじめに、前提となる"Next.js"と"microCMS"について簡単に説明します。
Next.js
React単体はUIライブラリなので、Webアプリケーションを作ろうと思ったらその他のさまざまなライブラリを組み合わせて使う必要があります。
それは大変だよね、ということで、ReactベースのWebアプリケーションを作成するためのオールインワンのフレームワークとして、Routingの機能や、Server Side Rendering (SSR) / Static Site Generation (SSG) などの機能を含んでいるのがNext.jsです。
私が所属するMiraiz開発部や、その他の開発部でもNext.jsは使われています。
microCMS
microCMSはAPIベースの日本製ヘッドレスCMSです。
Content Management System (CMS) は、ウェブサイトやデジタルコンテンツを作成、編集、管理、公開するためのソフトウェアやサービスのことです。
Wordpressなどに代表される従来型のCMSはフロントエンドとバックエンドの両方を提供していましたが、microCMSやContentfulなどのヘッドレスCMSはバックエンドのみを提供します。
ヘッドレスCMSを使う場合、フロントエンド部分については自前での実装およびホスティングが必要となりますが、その分画面のデザインの自由度が高く、さまざまなデバイスに対応可能となるのがメリットです。
参考記事: Headless CMSとは?今求められるその理由
1. Next.jsアプリケーションを作ろう
前提として Node.js がインストールされている必要があります。
また、以下のコマンドでyarnをインストールしておいてください。
$ npm install -g yarn
以下のコマンドでNext.jsアプリケーションを作成します。
$ yarn create next-app nextjs-microcms-app
いくつか聞かれますが、基本的にデフォルト(** で括られた方)で大丈夫です。
✔ Would you like to use TypeScript? … No / **Yes** ✔ Would you like to use ESLint? … No / **Yes** ✔ Would you like to use Tailwind CSS? … No / **Yes** ✔ Would you like to use `src/` directory? … **No** / Yes ✔ Would you like to use App Router? (recommended) … No / **Yes** ✔ Would you like to customize the default import alias (@/*)? … **No** / Yes
早速実行してみます。
$ cd nextjs-microcms-app $ yarn dev
http://localhost:3000/ をブラウザで開きます。
画面が表示されました🎉
2. microCMSをセットアップしよう
- https://microcms.io/ 「ログイン」あるいは「無料で始める」から会員登録
- https://app.microcms.io/create-service 「サービスを作成」で「一から作成する」をクリック
- サービス名とサービスIDを入力して「サービスを作成する」をクリック
- https://<サービスID>.microcms.io/create-api 「APIを作成」で「お知らせ」をクリック
「お知らせ」APIと「カテゴリ」APIが作成されます。
# 3. microCMSへの通信を実装しよう
Next.jsアプリケーションからmicroCMSへの通信を実装します。
microCMSが提供している https://github.com/microcmsio/microcms-js-sdk ライブラリを使います。
$ yarn add microcms-js-sdk
nextjs-microcms-app/.env.localを以下の内容で作成します。
- https://<サービスID>.microcms.io/create-api URLからサービスIDを確認
- https://<サービスID>.microcms.io/api-keys からAPIキーを確認
NEXT_PUBLIC_MICROCMS_API_URL=<サービスID> NEXT_PUBLIC_MICROCMS_API_KEY=<APIキー>
microCMSの「お知らせ」APIからお知らせ一覧・お知らせ詳細を取得するために、nextjs-microcms-app/lib/api.tsを以下の内容で作成します。
import { createClient } from "microcms-js-sdk"; // クライアントの作成 const client = createClient({ serviceDomain: process.env.NEXT_PUBLIC_MICROCMS_API_URL ?? "", apiKey: process.env.NEXT_PUBLIC_MICROCMS_API_KEY ?? "", }); // お知らせ用の型を定義 export interface News { id: string; title: string; content: string; } // お知らせ一覧を取得 export async function getNewsList(): Promise<News[]> { const data = await client.get({ endpoint: "news" }); return data.contents; } // お知らせ詳細を取得 export async function getNews(id: string): Promise{ const data = await client.get({ endpoint: "news", contentId: id, }); return data; }
4. ニュース一覧ページを実装しよう
nextjs-microcms-app/app/pages.tsxを編集します。
'use client' import { News, getNewsList } from '@/lib/api'; import Image from 'next/image' import Link from 'next/link'; import { useEffect, useState } from 'react'; export default function Home() { // お知らせ一覧の読み込み const [newsList, setNewsList] = useState<News[]>([]); useEffect(() => { getNewsList().then((newsList: News[]) => { setNewsList(newsList) }) }, []); return ( <main className="flex min-h-screen flex-col items-center ..."> <div className="z-10 max-w-5xl w-full items-center ..."> ... </div> <div className="relative flex place-items-center ..."> ... </div> {/* お知らせ一覧の表示 */} <div> {newsList.map(news => <Link key={news.id} href={`/news/${news.id}`}> <h2>{news?.title}-></h2> </Link>) } </div> </main> ) }
実行してみます。
$ yarn dev
http://localhost:3000/ をブラウザで開きます。
microCMSの「お知らせ」APIから取得した情報が表示されました。
試しに https://<サービスID>.microcms.io/apis/news の「追加」ボタンからお知らせを一件追加してみましょう。
http://localhost:3000/ をブラウザで再読込すると、追加した「お知らせ」のタイトルが表示されます🎉
5. ニュース詳細ページを実装しよう
microCMS「お知らせ」APIの「内容」を表示するためにhtml-react-parserを追加します。
$ yarn add html-react-parser
nextjs-microcms-app/app/news/[slug]/page.tsxを以下の内容で作成します。
'use client' import { News, getNews } from '@/lib/api'; import { useEffect, useState } from 'react'; import parse from 'html-react-parser'; export default function Page({ params }: { params: { slug: string } }) { // お知らせ詳細の読み込み const [news, setNews] = useState<news>(); useEffect(() => { getNews(params.slug ?? '').then((news: News) => { setNews(news) }) }, [params.slug]); // お知らせ詳細の表示 return ( <div> <h1> {news?.title} </h1> <p> {parse(news?.content ?? '')} </p> </div> ) }
実行してみます。
$ yarn dev
http://localhost:3000/ をブラウザで開いて、「(サンプル)まずはこの記事を開きましょう->」をクリックします。
http://localhost:3000/news/<お知らせID> へとページ遷移し、お知らせ詳細が表示されました🎉
おわりに
このように簡単な手順でmicroCMS APIとNext.jsアプリケーションを組み合わせることができました。
ブログやオンラインメディアなど、決まった形式の記事を一覧で表示するようなサイトであれば、microCMSをバックエンドとして利用し、Next.jsアプリケーションと繋ぐことで実現できることがイメージできたのではないかと思います。
データベースをはじめから自分で用意するのはハードルが高いですが、このようにヘッドレスCMSを利用することで、コンテンツの管理は外部サービスにまかせ、フロントエンドの実装から進めることができます。
microCMSはAPIベースなので、いずれ自分でバックエンドも用意した場合には、API単位で入れ替えることも容易です。
最初の開発をスピードアップするために、ヘッドレスCMSの利用を検討されてはいかがでしょうか。
参考までに、技育CAMPアカデミアの登壇で使用した資料のリンクを貼っておきます。
この資料では作成したアプリケーションをGoogle Cloud PlatformのCloud Runとしてデプロイする手順も紹介しています。そのためDockerfileを作成する前提となっており、ベースとなるサンプルおよび手順が異なります。また、この記事ではApp Routerベースのフォルダ構成ですが、資料作成時はPage Routerベースだったため、その点にも注意ください。
また、別日に登壇したそーたさんの記事もありますので、ぜひ見てみてください!
青木 美穂子 Mihoko Aoki
エンジニアリング統括部 MIRAIZ開発部 MIRAIZ開発グループ シニアエンジニア
新卒でIT企業へ入社。コンシューマ開発、金融・保険系プロジェクトへのサービスデリバリーなどを経て、Webアプリケーションフロントエンド開発のリーダーとしてBtoBサービスの開発に携わる。
※2023年12月現在の情報です。