Megu
Next.js + microCMS構成にサイトマップを追加する

Next.js + microCMS構成にサイトマップを追加する

2022.02.21

Next.js
microCMS

このブログでは新規記事はmicroCMSの管理画面から行い、
ISRを使用し動的に静的な記事ページを作成しています。
ビルド時にSitemap.xmlを出力しても新規記事を追加する度にsitemapが古くなってしまう...
そのため、Sitemapに関してはSSRで最新のsitemap.xmlを作成し、出力するよう作るというのがこの記事の内容となります。

実際のSSRのコード

import { format } from "date-fns";
import { GetServerSideProps } from "next";
import { getServerSideSitemap, ISitemapField } from "next-sitemap";

import { clientBlogs } from "../libs/microCMS/client";

type PostData = {
  id: string;
  updatedAt: string;
};

export const getServerSideProps: GetServerSideProps = async (context) => {
  const data = await clientBlogs.get({
    endpoint: "blogs",
    queries: { fields: "id,updatedAt" },
  });
  const postsData = data.contents;

  const fields: ISitemapField[] = [];
  postsData.forEach((data: PostData) => {
    fields.push({
      loc: `${process.env.NEXT_PUBLIC_SITE_URL}/blogs/${data.id}`,
      lastmod: format(new Date(data.updatedAt), "yyyy-MM-dd"),
      priority: 1,
      changefreq: "weekly",
    });
  });
  context.res.setHeader("Cache-Control","max-age=86400");
  return getServerSideSitemap(context, fields);
};

const Sitemap = () => null;
export default Sitemap;

使っているPackage

解説

microCMSから記事の一覧データを取得

const data = await clientBlogs.get({
    endpoint: "blogs",
    queries: { fields: "id,updatedAt" },
  });
  const postsData = data.contents;

microCMSのAPIよりブログ記事のidとupdatedAt(更新日時)のみの一覧データを取得します。

記事データを元にsitemapの中身を設定

const fields: ISitemapField[] = [];
  postsData.forEach((data: PostData) => {
    fields.push({
      loc: `${process.env.NEXT_PUBLIC_SITE_URL}/blogs/${data.id}`,
      lastmod: format(new Date(data.updatedAt), "yyyy-MM-dd"),
      priority: 1,
      changefreq: "weekly",
    });
  });
  context.res.setHeader("Cache-Control","max-age=86400");
  return getServerSideSitemap(context, fields);

lastmodに関しては、必ず更新日時を入れるようにしましょう!
明示的にその日の日時を入れて毎日更新しているように見せかけるなどは決してしてはいけません。
検索エンジンのクロラーの評価が下がります。
サーバー負荷軽減のためcacheを24Hとしています。

Pageとしての返却はnull

const Sitemap = () => null;

Page(ビュー)としての役割はないので返却値としては、nullに設定しておきましょう。

参考

https://zenn.dev/catnose99/articles/c441954a987c24