https://endaaman.me/sitemap.xml で見られる。
このサイト(というかブログ)はトップページと各メモ(記事)しかコンテンツはないので簡単に済んだ。
サーバーサイドでもReduxのstoreが見えているので、メモの一覧取得のアクション(getMemos
)をstore.dispatch(getMemos())
で発行して、返り値のPromiseを待ち受けて、そのコールバックでgetState().memo.items
で一覧を取得して、
import { createSitemap } from 'sitemap'
function buildSitemap(baseUrl, memos) {
function escapeQuery(url) {
const [path, query] = url.split('?')
if (!query) {
return url
}
return path + '?' + encodeURIComponent(query)
}
const urls = [
{
url: baseUrl + '/',
changefreq: 'daily',
}
]
for (const memo of memos) {
if (memo.draft) {
continue
}
const url = {
url: `${baseUrl}/memos/${memo.slug}`,
lastmodISO: (new Date(memo.updated_at)).toISOString(),
changefreq: 'weekly',
}
if (memo.image_url) {
url.img = escapeQuery(memo.image_url)
}
urls.push(url)
}
const sitemap = createSitemap({
cacheTime: 3 * (60 * 60 * 1000), // x hours
urls: urls
})
return sitemap.toString()
}
みたいなのを呼ぶだけ。今回このサイトのURLは/memo
の下にslug
フィールドをつなげただけのものなのでこんなもんで十分だったが、react-router
等で複雑なRoutingを実装してるとクライントサイドの設定から生成しなきゃいけなくなったりするので、なるべく扱うデータ(store)自体に一意なURLを生成するための情報をもたせる様な設計にしておくと良いだろう。