📍

@nuxt/sitemapで動的にサイトマップを作る

2023/01/08に公開

やりたいこと

静的なURLに加えて、URLにidが入っているものなど動的に生成されるURLも含めてsitemapを生成したい。
具体的にはGETのAPIを使用し仮にDBにデータが増えたとしても、 hoge/{hoge_id}/huga のようなURLを自動生成する。

尚、本コードはSSR環境で実行しています。
nuxt/sitemapではSSRでしか動作しないオプション、SPAのみで指定すべきオプション等が存在するため、どんな環境なのか把握しておくことが必要です。
(例: cacheTime)

インストール

パッケージをインストールします。
執筆当時のバージョンは 2.4.0 です。

yarn add @nuxtjs/sitemap

nuxt.config.js にモジュールを追加します。

nuxt.config.js
export default {
	modules: [
    '@nuxtjs/sitemap',
  ],
}

sitemapの生成

nuxt.config.jssitemap プロパティを追加します。
これだけで静的なURLは自動で生成されます。(便利)

nuxt.config.js
export default {
  modules: [
    '@nuxtjs/sitemap',
  ],
  sitemap: {
    path: '/sitemap.xml',
    exclude: [
      '/static/404.html',
      '/static/500.html',
    ],
    routes: [
      'hoge/123',
      'hoge/456',
    ],
  }
}

プロパティの意味は以下。詳細は公式ドキュメントを参照。

  • path
    • 作成するsitemapのパスを指定
      デフォルトは /sitemap.xml
  • exclude
    • sitemapに含めないパスを指定
  • routes
    • 静的なURL以外に動的に追加したいURLをここに記述
      後に記述するAPIを叩いてURLを生成する場合も、ここに記述する

他にも

  • hostname
    • generateした場合やSPAでは必要
  • cacheTime
    • sitemapの更新頻度を定義する
  • etag
    • etagキャッシュヘッダを設定する
  • gzip
    • sitemapをgzip形式に圧縮する場合に指定
  • i18n
    • nuxt-i18nモジュールを使用し、ロケールを設定

など様々なオプションが存在する。

動的に生成する

非同期でAPIを叩き、返ってきたデータからURLを生成してみます。
ここでは仮にブログ一覧を取得するAPIを使用する。

nuxt.config.js
import axios from 'axios';

export default {
  modules: [
    '@nuxtjs/sitemap',
  ],
  sitemap: {
    path: '/sitemap.xml',
    exclude: [
      '/static/404.html',
      '/static/500.html',
    ],
    // 以下、変更
    async routes() {
      return await axios
        .get('hogehoge/v1/articles')
        .then((articleList) => {
          return articleList.data.map(
            (article) =>
              `hoge/${article.id}/huga`
          );
        });
    },
  }
}

これでsitemap.xmlというファイルに生成したいURLが全て出力されますが、5000件を超えるURLを記載する場合はファイルを分割する必要があります。

分割するためには sitemaps オプションを追加し、その中でrouteを記述します。

nuxt.config.js
import axios from 'axios';

export default {
  modules: [
    '@nuxtjs/sitemap',
  ],
  sitemap: {
    path: '/sitemap.xml',
    exclude: [
      '/static/404.html',
      '/static/500.html',
    ],
    // 以下、変更
    sitemaps: [
      {
        path: '/sitemap-1.xml',
        async routes() {
          return await axios
            .get('hogehoge/v1/articles')
            .then((articleList) => {
              return articleList.data.map(
                (article) =>
                  `hoge/${article.id}/huga`
              );
            });
        },
      },
      {
        path: '/sitemap-2.xml',
        async routes() {
          return await axios
            .get('hogehoge/v1/comments')
            .then((commentList) => {
              return commentList.data.map(
                (comment) =>
                  `hoge/${comment.id}/huga`
              );
            });
        },
      },
    ],
  }
}

これで設定完了です。

参考

Discussion