2020/05/22

nodejsを使ってsitemapを作成する

seojavascript

概要

sitemapを作成して、Google Search Consoleに登録したいなというモチベーションが湧いてきたので、実施しました。

検討事項

Nuxt.jsのmoduleとして@nuxtjs/sitemapが良さそうだったんですが・・将来的に以下のようなことも視野に入れ・・

  • cronなどを使っての定期的なsitemapの更新
  • apiサーバーと連携して、apiで新データが登録されたら自動でsitemapを更新

今回はnodejsのsitemapモジュールを使って、単一実行ファイルを作成して対応しました。

実施事項

(少しデフォルメはしてますが)以下のようなjsファイルを作成しました。

sitemap-generator.js

const { resolve } = require('path')
const { createGzip } = require('zlib')
const { createWriteStream } = require('fs')
const axios = require('axios')
const { SitemapStream } = require('sitemap')
const hostname = 'https://your-site.com'
const apiBaseUrl = 'https://api.your-site.com/api/v1'

async function getUrlsByAPI() {
  const { data } = await axios.get(`${apiBaseUrl}/your-entities/`)
  return data.map((item) => {
    return {
      url: `/your-entities/${item.slug}`,
      lastmod: item.updated_at,
      changefreq: 'weekly'
    }
  })
}

async function generate() {
  // streamを開きます
  const sitemapStream = new SitemapStream({
    hostname
  })
  // streamに書き込んだら、自動的にsitemap.xml.gzに書き込まれるようにします
  sitemapStream
    .pipe(createGzip())
    .pipe(createWriteStream(resolve('./sitemap.xml.gz')))
  // staticなrouteを処理
  sitemapStream.write({
    url: '/',
    changefreq: 'daily'
  })
  sitemapStream.write({
    url: '/about',
    changefreq: 'monthly'
  })
  // apiデータが必要な動的なrouteを処理
  const urls = await getUrlsByAPI()
  urls.forEach((url) => {
    sitemapStream.write(url)
  })
  sitemapStream.end()
}

generate()
  .then(() => {
    console.log('sitemap generation completed!!')
  })
  .catch((error) => {
    console.log(error)
  })

これを以下で実行すると・・

node sitemap-generator.js

同一フォルダに “sitemap.xml.gz” が出力されます。