過去にこちらの方法を使ってastro-notion-blogをsitemapに対応させました。
しかし、sitemap.index.xml
とsitemap-0.xml
の2ファイルが出力される点がどうにも気持ち悪く、また、lastmod
を自分で指定したかったため、自力で対応させることにしました。
(参照)📄astro-notion-blogで記事に更新日を表示する
- lastmodには、あれば更新日、なければ作成日を入れる
- 作られるファイルは
sitemap.xml
- 既存のモジュールを可能な限り使う
- インテグレーションを使わない(使い方が分からない)
- @astrojs/sitemapを使わない(使い方が分からない)
参考src\pages\feed.ts
の中身
type SitemapItem = {
loc: string
lastmod: Date
}
function formatDate(date: Date): string {
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
export function generateSitemap(items: SitemapItem[]) {
const itemsStr = items
.map(
({ loc, lastmod }) =>
`<url><loc>${loc}</loc><lastmod>${formatDate(lastmod)}</lastmod></url>`
)
.join('')
return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${itemsStr}
</urlset>
`
}
import { generateSitemap } from '../lib/generate-sitemap'
import { getAllPosts } from '../lib/notion/client'
import { getPostLink } from '../lib/blog-helpers'
export async function GET() {
const [posts] = await Promise.all([getAllPosts()])
const sitemapItems = posts.map((post) => {
const updateDate = post.UpdateDate ? new Date(post.UpdateDate) : null
const lastmod = updateDate || new Date(post.Date)
return {
loc: new URL(getPostLink(post.Slug), import.meta.env.SITE).toString(),
lastmod,
}
})
const sitemap = generateSitemap(sitemapItems)
const res = new Response(sitemap)
res.headers.set('Content-Type', 'text/xml')
return res
}
public\
直下にrobots.txt
を配置する。
クローラーには全て許可、サイトマップのパスを記述する。
User-agent: *
Allow: /
Sitemap: https://サイトによって違う/sitemap.xml
sitemap.xml.ts
という拡張子は本当にこれでいいの??と不安になるものでしたが、ビルド時に.ts
の拡張子が削除されてしまうので作成したいファイル名の拡張子を入れなきゃいけないとAstroのドキュメントに書いてありました。
最初にドキュメントを読んでおくべきでしたね。