【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
にサイトマップの設定を追記すれば完了。