【Astro】サイトマップ(sitemap.xml)をインテグレーションなしで自作する
Astroには公式インテグレーションの@astrojs/sitemapがあるおかげで、npx astro add sitemapを叩くだけでpages配下の各ルートを全て含んだxmlファイルを自動で作成してくれるため、非常に簡単にサイトマップを配置できる。
しかしその反面、当サイトのようなブログサイトでありがちな下記要件を満たすのは少し手間がかかる。
- 記事の更新日を
lastmodに指定したい noindexにしている記事(パス)を除外したいsitemap.xmlというファイル名で作成したい(上記インテグレーションだとsitemap-index.xmlとsitemap-0.xmlの2ファイルが作成されてしまう)
インテグレーションをカスタムするという方法もあるが、今後改修する際の融通も効きやすさを考慮して今回はサイトマップを自前で実装してみる。
実装方法
0. サンプル記事の用意
type Article = {  path: string;  updatedAt: Date;  index: boolean;};
export const EXAMPLE_ARTICLES: Article[] = [  {    path: "/article-001",    updatedAt: new Date(),    index: true,  },  {    path: "/article-002",    updatedAt: new Date(),    index: true,  },  {    path: "/article-003",    updatedAt: new Date(),    index: false,  },];今回は例として上記のようなArticleオブジェクト群を用いる。
3つ目の記事だけnoindexにしたいという前提で、それぞれのupdatedAtは適当に指定している。
1. xmlの構築
type SitemapItem = {  loc: string;  lastmod: Date;};
export function generateSitemap(items: SitemapItem[]) {  const itemsStr = items    .map(      ({ loc, lastmod }) =>        `<url><loc>${loc}</loc><lastmod>${lastmod.toJSON()}</lastmod></url>`,    )    .join("");
  return `<?xml version="1.0" encoding="UTF-8"?>   <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">     ${itemsStr}   </urlset> `;}サイトマップの中身を生成する関数を作成する。
2. APIルートの定義
import { generateSitemap } from "../utils/generateSitemap";import { EXAMPLE_ARTICLES } from "../utils/consts";
export async function GET() {  const sitemapItems = EXAMPLE_ARTICLES.filter((article) => article.index).map(    (article) => {      return {        loc: "https://example.com" + article.path,        lastmod: article.updatedAt,      };    },  );  const sitemap = generateSitemap(sitemapItems);
  const res = new Response(sitemap);  res.headers.set("Content-Type", "text/xml");
  return res;}/sitemap.xmlというエンドポイントでレスポンスを返すために、src/pages/sitemap.xml.tsを作成しAPIルートを定義する。
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">    <url>        <loc>https://example.com/article-001</loc>        <lastmod>2023-09-15T12:25:26.998Z</lastmod>    </url>    <url>        <loc>https://example.com/article-002</loc>        <lastmod>2023-09-15T12:25:26.998Z</lastmod>    </url></urlset>試しにhttp://localhost:4321/sitemap.xmlを叩いてみると、無事期待通りのxmlが返ってきた。noindexにしたい記事もしっかり除外されている。
3. サイトマップの登録
<head>  <link rel="sitemap" href="/sitemap.xml" /></head>Sitemap: <ORIGIN>/sitemap.xmlあとはクローラー向けに、<head>内とrobots.txtにサイトマップの設定を追記すれば完了。