【Nuxt3】SSG時に、サイトマップを動的ルートも含めて全自動で生成する方法

2023/06/01 15:42公開
2023/08/30 11:38最終更新
Table of Contents
  1. 経緯
  2. コード

経緯

Google Search Index用にサイトマップを作りたくなった。サイトマップの生成自体はsitemapパッケージでどうにかなるが、いちいち全部のルートを取得してリストを作るのは面倒臭い。そこで、nitroに備わっているクローラーを使って、サイト内にあるリンクからルート一覧を生成してみる。

nitroのクローラーは、HTMLに含まれる、「/」で始まるhref属性を含むタグを自動的に認識し、リンク先のルートを生成できる。

nitroでは、クローラーによって自動的に動的ルートのページが生成される。しかし、クロール後のルート一覧を取得する方法が存在しない。そこで、ページを生成するタイミングでフックを挟んで、変数のリストに追加していくことにする。

コード

まず、sitemapパッケージをインストールしておく。

yarn add sitemap

次に、nuxt.config.tsdefineNuxtConfigの上に以下を追加する。

const hostname = "<hostname>"
const routes: string[] = []

export default defineNuxtConfig({
...

続いて、defineNuxtConfigの中に以下を追加する。

export default defineNuxtConfig({
...
  nitro: {
    hooks: {
      "prerender:route"(route) {
        routes.push(route.route)
      },
      close() {
        if (routes.length > 0) {
          const links: SitemapItemLoose[] = routes.map(route => ({
            url: route,
          }))

          const stream = new SitemapStream({
            hostname,
          })

          return streamToPromise(Readable.from(links).pipe(stream))
            .then((sm) => {
              return fs.writeFileSync("dist/sitemap.xml", sm.toString())
            })
        }
      },
    },
  },
...
})

9行目のif (routes.length > 0)は、これを入れないとnuxt prepare(yarn install)を実行した際にもこの処理が走ってしまうために入れています。