Main featured image

Next.js/TypeScriptプロジェクトのbuild時にsitemap.xmlを自動生成する

Next.js
TypeScript
SEO

Next.js/TypeScript プロジェクトの build 時に sitemap.xml を自動生成する方法です。

ブログ記事やコンテンツの作成・更新毎に生成サイトなどで sitemap.xml を作成していた手間を自動化しましょう。

環境
  • macOS Catalina 10.15.5(19F101)
  • VSCode 1.52.1
  • Next 10.0.5
  • React 16.14.0
  • TypeScript 4.0.5
  • Yarn 1.22.4
  • Node 14.9.0
前提

以下のディレクトリ構成を想定します。

プロジェクトルートディレクトリ(package.json がある階層)配下にソースコードがある src/pages 、ブログ記事の markdown がある src/posts と大きく2つのディレクトリがあるディレクトリ構成です。

src/.
├── pages
│   ├── _app.tsx
│   ├── _document.tsx
│   ├── index.tsx
│   ├── posts
│   │   └── [id].tsx
│   └── privacy.tsx
├── posts
│   ├── post1.md
│   ├── post2.md
│   └── post3.md
Prettier package を install する

sitemap.xml のフォーマット処理を行う為、コードフォーマッターの Prettier を install します。

yarn add -D prettier
sitemap.xml を出力するスクリプトを実装する

プロジェクトルートディレクトリ(package.json がある階層)に scripts という名前のディレクトリを作成し、 scripts/sitemap-generator.js ファイルを作成します。

以下実装内容です。

const fs = require('fs');
const globby = require('globby');
const prettier = require('prettier');

const WEBSITE_DOMAIN = 'https://website.com';
const SITEMAP_XML = 'sitemap.xml';

const formatted = (sitemap) => prettier.format(sitemap, { parser: 'html' });

(async () => {
  const paths = await globby([
    // include
    'src/pages/*.tsx', // index.tsxなど固定ページをsitemapに含める
    'src/posts/*.md', // markdownをsitemapに含める
    // exclude
    '!src/pages/_*.tsx', // _app.tsx _document.tsxを除外する
  ]);

  const pages = paths.map((path) => {
    const stats = fs.statSync(path);
    return {
      path: path,
      updateDate: stats.mtime,
    };
  });

  const pagesSitemap = `
    ${pages
      .map((page) => {
        const path = page.path
          .replace('src/pages/', '')
          .replace('src/', '')
          .replace('.tsx', '')
          .replace('.md', '')
          .replace(/\/index/g, '');
        const routePath = path === 'index' ? '' : path;
        return `
          <url>
            <loc>${WEBSITE_DOMAIN}/${routePath}</loc>
            <lastmod>${page.updateDate.toISOString()}</lastmod>
          </url>
        `;
      })
      .join('')}
  `;

  const generatedSitemap = `
    <?xml version="1.0" encoding="UTF-8"?>
    <urlset
      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
    >
      ${pagesSitemap}
    </urlset>
  `;

  fs.writeFileSync(`public/${SITEMAP_XML}`, formatted(generatedSitemap), 'utf8');
})();

この sitemap.xml 生成スクリプトは Node.js で動作させる為、 importrequire になっていたり Node.js の記述になっています。

WEBSITE_DOMAIN は対象の website ドメインに修正してください。

src/pagessrc/posts 配下のファイル名から 固定ページと記事ページの URL を生成して sitemap の xml を構築し、public/sitemap.xml として出力します。

sitemap.xml のページ更新日時を指定するプロパティ lastmod には固定ページの tsx ファイル、記事コンテンツの markdown ファイルの更新日時を出力しています。

sitemap.xml が出力されるか確認する

プロジェクトルートディレクトリから以下コマンドを実行します。

node scripts/sitemap-generator.js

public ディレクトリ配下に以下 sitemap.xml が出力されていれば成功です。

<?xml version="1.0" encoding="UTF-8"?>
<urlset
  xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
>
  <url>
    <loc>https://website.com/</loc>
    <lastmod>2021-01-15T04:30:55.379Z</lastmod>
  </url>

  <url>
    <loc>https://website.com/privacy</loc>
    <lastmod>2021-01-15T04:30:55.379Z</lastmod>
  </url>

  <url>
    <loc>https://website.com/posts/post1</loc>
    <lastmod>2021-01-15T04:30:55.379Z</lastmod>
  </url>

  <url>
    <loc>https://website.com/posts/post2</loc>
    <lastmod>2021-01-15T04:30:55.379Z</lastmod>
  </url>

  <url>
    <loc>https://website.com/posts/post3</loc>
    <lastmod>2021-01-15T04:30:55.379Z</lastmod>
  </url>
</urlset>
build 時に sitemap.xml を自動生成する設定ファイル next.config.js 作成

プロジェクトルートディレクトリ直下に next.config.js を作成してください。

以下設定内容です。

module.exports = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      require('scripts/sitemap-generator');
    }
    return config;
  },
};

isServer=false 時(クライアントビルド時)に scripts/sitemap-generator を読み込んで sitemap.xml を生成しています。

yarn devyarn build コマンドを実行してください。

public/sitemap.xml ファイルが生成されていれば成功です。

これで build 時の sitemap.xml の自動生成設定は完了です。

robots.txt の作成

Google のクローラーに sitemap.xml の場所を教えてクロールの促進をさせる為、public ディレクトリ直下に robots.txt を作成します。

設定内容としては以下となります。

User-Agent: *
Disallow:
Sitemap:https://your.website.com/sitemap.xml

User-Agent: * で全てクローラーを対象として、 Disallow: で全てのページのクローリングを許可します。

最後に Sitemap: に sitemap.xml がある URL を指定します。

この後 Google Search Console に sitemap.xml を登録するので、ホスティングサービスにデプロイして sitemap.xml/robots.txt を公開してください。

Google Search Console に sitemap.xml を登録する
post image

Google Search Console を開き、ドメインを登録します。

ドメイン名を入力して 続行 ボタンをクリックしてください。

post image

ドメインの所有権を確認する為、 TXTレコード をコピーしてください。

post image

筆者の場合、お名前.com でドメインを取得したので、お名前.com の DNS レコードの作成から、Google Search Console の TXT レコードを登録しました。

post image

Google Search Console に戻り、先程のドメイン所有権の確認ダイアログの 確認 ボタンをクリックしてください。

DNS の変更が適用されるまでに時間がかかる場合があるので、所有権の確認が取れない場合は時間を置いて再度試してください。

筆者の場合、所有権の確認が取れるまで 1 時間程かかりました。

post image

最後にサイトマップ画面を開いて、先程公開した sitemap.xml の URL を入力し 送信 ボタンをクリックして sitemap.xml の登録は完了です。

おわりに

sitemap.xml を記事作成・更新時に生成サイトなどで都度生成するのはやはり手間がかかります。

build 時に sitemap.xml を自動生成・更新しておけば記事を書くハードルが一つ下がるので是非お試し下さい。

こちらは sitemap.xml 自動生成設定をした本 Web サイト repository になりますので参照ください。

Written by ZUMA a.k.a. Kazuma. Web/Mobile App developer.  My profile.
Tags
Archives
2021-102021-092021-072021-062021-052021-042021-032021-022021-01
Recent Posts