astro-notion-blogでサイトマップに対応する

Featured image of the post

目次

まえがき

過去にこちらの方法を使ってastro-notion-blogをsitemapに対応させました。

しかし、sitemap.index.xmlsitemap-0.xmlの2ファイルが出力される点がどうにも気持ち悪く、また、lastmodを自分で指定したかったため、自力で対応させることにしました。

やりたいこと

(参照)📄Arrow icon of a page linkastro-notion-blogで記事に更新日を表示する

  • lastmodには、あれば更新日、なければ作成日を入れる
  • 作られるファイルはsitemap.xml
  • 既存のモジュールを可能な限り使う
  • インテグレーションを使わない(使い方が分からない)
  • @astrojs/sitemapを使わない(使い方が分からない)

TypeScriptでサイトマップを実装

参考
src\pages\feed.tsの中身

generate-sitemap.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>
 `
}
src\lib\generate-sitemap.ts

sitemap.xml.tsを新規作成

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
}
src\pages\sitemap.xml.ts

robots.txtを追加

public\直下にrobots.txtを配置する。

クローラーには全て許可、サイトマップのパスを記述する。

User-agent: *
Allow: /

Sitemap: https://サイトによって違う/sitemap.xml
public\robots.txt

あとがき

sitemap.xml.tsという拡張子は本当にこれでいいの??と不安になるものでしたが、ビルド時に.tsの拡張子が削除されてしまうので作成したいファイル名の拡張子を入れなきゃいけないとAstroのドキュメントに書いてありました。

最初にドキュメントを読んでおくべきでしたね。