LoginSignup
9
0

More than 1 year has passed since last update.

Next.jsにmicroCMS連携してブログサイト作ってみた

Last updated at Posted at 2023-04-04

この記事の目的

  • Next.jsでブログを作成したときの備忘録
  • Next.jsで指定したID情報をAPI取得する

概要

Next.jsでブログサイトの側だけ作成したので、APIでブログのデータを取得し表示する部分についてまとめています。
APIについてはmicroCMSを使用しています。
実際のブログ記事はこちら
スクリーンショット 2023-04-02 21.56.39.png

全体の流れ

  • ①microCMS登録
  • ②microCMSの準備(ブログ基本情報、ブログ記事作成)
  • ③Next.jsでAPI設定
  • ④Next.jsでライブラリのインストール
  • ⑤Next.jsでAPI取得処理の実装

①microCMS登録

microCMSとは

APIベースの日本製の中でも最も代表的なヘッドレスCMSです。国産のヘッドレスCMSとして最初に誕生し、国内では最も多くの利用者を誇ります。マニュアルが丁寧にまとめられており利用しやすいことでも人気を集めております。

簡単にいうとmicroCMSを使えば、ものすごく簡単にAPIの作成が行えるってことですかね

microCMS登録についてはmicroCMSのはじめ方を参考にして下さい。
アカウント登録はすぐ終わります

②microCMSの準備(ブログ基本情報、ブログ記事作成)

サービス作成

スクリーンショット 2023-04-02 22.20.54.png

API作成

サービス作成後「コンテンツ(API)」部分の「+」をクリックしAPIを作成していきます
スクリーンショット 2023-04-02 22.22.42.png
API名とエンドポイント名を決めていきます。
スクリーンショット 2023-04-02 22.23.36.png

APIのフィールド設定(APIスキーマ)

スクリーンショット 2023-04-02 22.28.38.png
本記事で紹介しているブログのフィールド設定は下記のようになっています

フィールドID 表示名 種類
title  タイトル  テキストフィールド
description  サブタイトル  テキストフィールド
content  内容  リッチエディタ
img  アイキャッチ  画像
category  カテゴリ  セレクトフィールド
type  ブログ種別  セレクトフィールド
authorName  著者名  セレクトフィールド
authorImg  著者画像  画像
authorDirector  著者役職  セレクトフィールド

ブログ記事作成

APIのフィールド設定が完了したらテスト用にブログを作成していきます。
APIフィールドは後から追加もできるので、慣れてきてから設定を増やすのもありかと思います
スクリーンショット 2023-04-02 22.29.24.png

③Next.jsでAPI設定

ここまででAPIとブログの作成が完了したので、Next.js側で呼び出せるように設定していきます。

.env
API_KEY=APIキーを貼り付ける
MICROCMS_ENDPOINT=blogs
MICROCMS_DOMAIN=pikimarublog

API_KEYは以下の画像の「APIキー」をクリック後に出てくるAPIキーを貼り付けて下さい
スクリーンショット 2023-04-02 22.59.34.png
MICROCMS_ENDPOINTは以下の画像のエンドポイントに記載あるものを記載する
MICROCMS_DOMAINは「microcms.io」の前の部分を記載する
スクリーンショット 2023-04-02 23.00.43.png

④Next.jsでライブラリのインストールと

microcms-js-sdkをインストール

APIリクエストには公式が提供しているmicrocms-js-sdkを使います。
microCMSのJavaScript SDK公式サイト

npm install microcms-js-sdk

⑤Next.jsでAPI取得処理の実装

microCMSと接続

microCMSと接続を行う部分の記載をしていきます。
今回はlibディレクトリにclient.tsxというファイルを作成しています
serviceDomainapiKeyの値は 先ほど設定したenvファイルを参照します。

lib/client.tsx
import { createClient } from "microcms-js-sdk";

// microCMSと接続 
export const client = createClient({
    serviceDomain: process.env.MICROCMS_DOMAIN || '',
    apiKey: process.env.API_KEY || '',
})

APIからデータを取得

ここでは一度最新のブログ記事を100件取得しそのから直近の15件を画面表示するように取得しています

pages/index.tsx
import { Format } from '../layout/format'
import { Latest } from '../components/latest'

import type { Blog } from '../types/blog';
import { client } from "../lib/client";

type Props = {
  latestBlogs: Array<Blog>;
};

export default function Home({ latestBlogs }: Props) {
  return (
    <Format>
      <Latest blogs={latestBlogs} />
    </Format>
  )
}

export const getStaticProps = async () => {
  // APIからブログデータを全て取得
  const allData = await client.get({
    endpoint: process.env.MICROCMS_ENDPOINT || '',
    queries: {
      orders: '-createdAt', limit: 100 // 100件取得
    }
  });
  // const allBlogs = allData.contents;
  const allBlogs: Blog[] = allData.contents;

  // 最新のブログ記事を15件取得し「latestBlogs」に格納
  const latestBlogs = allBlogs.slice(0, 15);

  return {
    props: {
      latestBlogs,
    },
  }
};

カテゴリごとやブログの種別ごとに取得している`pages/index.tsx`コードをクリックして全て表示
pages/index.tsx
import { Format } from '../layout/format'
import { Trending } from '../components/trending'
import { Latest } from '../components/latest'
import { Popular } from '../components/popular'
import { Category } from '../components/category'

import type { Blog } from '../types/blog';
import { client } from "../lib/client";

type Props = {
  latestBlogs: Array<Blog>;
  trendBlogs: Array<Blog>;
  popularBlogs: Array<Blog>;
  categoryBlogs: Record<string, Array<Blog>>; // categoryごとに分けた配列を持つオブジェクト
};

export default function Home({ trendBlogs, latestBlogs, popularBlogs, categoryBlogs }: Props) {
  return (
    <Format>
      <Trending blogs={trendBlogs} />
      <Latest blogs={latestBlogs} />
      <Popular blogs={popularBlogs} />
      <Category blogs={categoryBlogs as Record<string, Blog[]>} />
    </Format>
  )
}

export const getStaticProps = async () => {
  // APIからブログデータを全て取得
  const allData = await client.get({
    endpoint: 'blogs',
    queries: {
      orders: '-createdAt', limit: 100 // 100件取得
    }
  });
  // const allBlogs = allData.contents;
  const allBlogs: Blog[] = allData.contents;

  // 最新のブログ記事を15件取得し「latestBlogs」に格納
  const latestBlogs = allBlogs.slice(0, 15);

  // ブログ種別(type)がtrenddeあるデータを取得し「trendBlogs」に格納する
  const trendData = allBlogs.filter((blog) => blog.type.includes('trend'));
  const trendBlogs = trendData.slice(0, 10);

  // ブログ種別(type)がpopularのものから15件取得し「popularBlogs」に格納
  const popularData: Array<Blog> = allBlogs.filter(blog => blog.type.includes('popular'));
  // 最新順に15件取得し「popularBlogs」に格納
  const popularBlogs: Array<Blog> = popularData.slice(0, 10);

  // カテゴリーごとにデータを整理し「categoryBlogs」に格納
  const categoryBlogs: Record<string, Array<Blog>> = {}; // categoryごとに分けたオブジェクトを用意
  allBlogs.forEach((blog) => {
    if (categoryBlogs[blog.category]) {
      // すでにカテゴリーの配列があれば追加
      categoryBlogs[blog.category].push(blog);
    } else {
      // カテゴリーの配列がなければ新しく作成
      categoryBlogs[blog.category] = [blog];
    }
  });

  return {
    props: {
      latestBlogs,
      trendBlogs,
      popularBlogs,
      categoryBlogs,
    },
  }
};

補足

「process.env.API_KEYがundefined」のエラーといったようなエラーが出た場合は以下の2点を試してみて下さい

  • npm run devを再度実行
  • next.config.jsに環境変数の設定する

next.config.js に環境変数の設定が含まれていないとエラーが発生する可能性があります
nextConfig オブジェクトに env を追加して、環境変数を設定しましょう。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  images: {
    domains: ['images.microcms-assets.io'],
  },
  env: {
    API_KEY: process.env.API_KEY,
  },
};

module.exports = nextConfig;

まとめ

今回はmicroCMSを使用してブログ記事をAPI取得できるようにしてみました。
microCMSとVercelを連携することでmicroCMSでブログを作成や変更した際に自動的にビルドされてブログが更新されるのでかなり便利だと感じました。
ブログ自体はスタイルやその他コンテンツがまだ追加できていない箇所が多いのでこれからどんどん追加していきたいな、、

9
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
0