みなさんこんにちは!
イザナギです!
Sitemaps(サイトマップ)標準は、ウェブマスターがサーチエンジンに、サイト内でクロールすべきURLを教えるための方式を規定するものである。サイトマップは、当該サイトにおけるURL全てをリストした、XMLファイルとして提供し、ウェブサイト運営者は各URLに付加的情報として、最終更新日時や更新頻度、他のURLとの相対的な重要度を加えたりできる。Sitemapsに対応したサーチエンジンでは、この情報を使って、サイトのクロールをより効率的に行えるようになる。サイトマップはサーチエンジンへのURL追加規約であり、URL排除規約であるrobots.txtを補完するものである。 https://ja.wikipedia.org/wiki/Sitemaps
import { mkdirSync, writeFileSync, copyFile } from 'fs'
import { Readable } from 'stream'
import { dirname } from 'path'
import { SitemapStream, streamToPromise } from 'sitemap'
import { defineNuxtModule, createResolver } from '@nuxt/kit'
// https://github.com/benoitdemaegdt/nuxt3-sitemap
export default defineNuxtModule({
meta: {
name: 'sitemap',
version: '0.0.1',
configKey: 'sitemap',
compatibility: { nuxt: '^3.0.0-rc.12' },
},
defaults: {
hostname: 'http://localhost:3000',
},
async setup(options, nuxt) {
async function generateSitemap(routes) {
const sitemapRoutes = routes.map((route) => route.path)
// https://github.com/ekalinin/sitemap.js#generate-a-one-time-sitemap-from-a-list-of-urls
const stream = new SitemapStream({ hostname: options.hostname })
return streamToPromise(Readable.from(sitemapRoutes).pipe(stream)).then(
(data) => data.toString()
)
}
function createSitemapFile(sitemap, filepath) {
const dirPath = dirname(filepath)
mkdirSync(dirPath, { recursive: true })
writeFileSync(filepath, sitemap)
}
const resolver = createResolver(import.meta.url)
const filePath = resolver.resolve(
nuxt.options.srcDir,
'node_modules/.cache/.sitemap/sitemap.xml'
)
nuxt.options.nitro.publicAssets = nuxt.options.nitro.publicAssets || []
nuxt.options.nitro.publicAssets.push({
baseURL: '/',
dir: dirname(filePath),
})
nuxt.hook('nitro:build:before', (nitro) => {
const paths = []
const EXCLUDED_KEYWORDS = ['/api/_content', '_payload.js', '200.html']
nitro.hooks.hook('prerender:route', (route) => {
const shouldBeAddedToSitemap = EXCLUDED_KEYWORDS.every(
(excludedKeyword) => !route.route.includes(excludedKeyword)
)
if (shouldBeAddedToSitemap) {
paths.push({ path: route.route })
}
})
nitro.hooks.hook('close', async () => {
const sitemap = await generateSitemap(paths)
createSitemapFile(sitemap, filePath)
const outptFilepath = resolver.resolve(
nuxt.options.srcDir,
'.output/public/sitemap.xml'
)
copyFile(filePath, outptFilepath, (err) => {
if (err) {
console.log('sitemap.xml No created')
console.log(err)
} else {
console.log('sitemap.xml created')
}
});
})
})
},
})
「copyFile」を使用し、「.output/public/sitemap.xml」のファイルを「node_modules/.cache/.sitemap/sitemap.xml」の内容に更新(上書きコピー)するように修正しただけです。
私が試したところ、修正後のコードでは、1回目の「yarn generate」時にも「.output/public/sitemap.xml」が作られるようになっていました!
まとめ
今回はNuxt3でサイトマップを作成する方法を紹介いたしました。
「nuxt/sitemap」がNuxt3で使えれば使ったのですが、まだ対応していないようでしたので、
違うコードを利用しての実装となりました。
「nuxt/sitemap」のNuxt3サポートが対応したら、書き換えようかなとは思っています。
それではまた次回の記事でお会いしましょう!