Next.jsサイトにsitemapを実装する

2021/01/18

/pages/sitemap.xml.tsx
import React from 'react';
import { GetServerSideProps } from 'next';

import { SITE_URL } from '../utils/env';
import { mergeUrlAndSlug, UrlTable } from '../utils/path/url';
import { getAvailableSlugs } from '../utils/article/fs.server';

const FIXED_URLS = [UrlTable.root, UrlTable.about, UrlTable.blog];
const siteUrl = SITE_URL.slice(0, -1);

const genUrl = (url: string) => `<url><loc>${siteUrl + url}</loc></url>`;
const genFromSlugs = async (urlBase: string, urlPost: string) => {
  const slugs = await getAvailableSlugs(urlBase);
  return slugs.map((slug) => genUrl(mergeUrlAndSlug(slug, urlPost)));
};

export const getServerSideProps: GetServerSideProps = async ({ res }) => {
  const smFixed = FIXED_URLS.map((url) => genUrl(url));
  const smBlogPosts = await genFromSlugs(UrlTable.blog, UrlTable.blogPosts);

  const sitemap = [...smFixed, ...smBlogPosts].join('');

  if (res) {
    res.setHeader('Content-Type', 'text/xml');
    res.write(`<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${sitemap}
    </urlset>`);
    res.end();
  }

  return {
    props: {},
  };
};

const Sitemap: React.FC = () => null;

export default Sitemap;

sitemap も pages でレンダリングする。コツはファイル名を /pages/sitemap.xml.tsx として XML を返すことを明示することと、SSR(getServerSideProps) の res.setHeadertext/xml として返すこと。

  • SSG のページは、固定の URL テーブルを作成して、それを返す。
  • slug などの dynamic route を使っているページは、getStaticPaths で利用している関数をそのまま sitemap.xml.tsx でも利用すればよい

references

Writings

blogsnippetcourse
Home©︎ suzukalight