Eleventy ビルドで sitemap.xml と robots.txt を自動生成
Eleventy のドキュメントビルド時に SEO 必須の sitemap.xml と robots.txt を自動生成し、Docs の公開パイプライン全体で自動的に提供できるようになりました。
背景
SEO 監査で /sitemap.xml と /robots.txt が 404 となっていることが指摘され、検索エンジンのインデックス付与とクロール制御が不十分でした。Webawesome のドキュメントはスタンドアロンのビルドと webawesome-app への組み込みの二つの形態で配布されるため、手動でファイルを配置する運用はミスが起きやすく保守コストが高くなります。そこでビルドプロセスに sitemap と robots.txt の生成ロジックを組み込み、ビルド結果に必ず含める設計が採用されました。
技術的な変更
Sitemap collection の導入 と HtmlBasePlugin の有効化により、公開対象の URL を絞り込んだコレクションを生成します。.eleventy.js では addCollection('sitemap', ...) が追加され、noindex や eleventyExcludeFromCollections が設定されたページ、管理画面系パス(/admin など)およびエラーページを除外するフィルタリングロジックが実装されています。
// Sitemap collection: public, indexable URLs only.
const SITEMAP_EXCLUDE_PATTERNS = [
/^\/admin(\/|$)/,
/^\/workspaces(\/|$)/,
// ... 省略
];
eleventyConfig.addCollection('sitemap', collection => {
return collection
.getAllSorted()
.map(item => {
const raw = String(item.data.ogUrl || item.url || '').replace(/\.njk$/, '');
const urlPath = raw.replace(/^https?:\/\/[^/]+/, '');
return { item, urlPath };
})
.filter(({ item, urlPath }) => {
if (!urlPath) return false;
if (item.data.noindex) return false;
if (item.data.eleventyExcludeFromCollections) return false;
if (SITEMAP_EXCLUDE_PATTERNS.some(re => re.test(urlPath))) return false;
// ... 省略
return true;
})
.map(({ item, urlPath }) => ({ path: urlPath, lastmod: item.date }));
});
sitemap.xml.njk テンプレートは 11ty のベースブログパターンを踏襲し、layout: false により XML が HTML ラップされないようにしています。htmlBaseUrl(siteMetadata.url) フィルタで絶対 URL に変換し、将来的にパスプレフィックスが付くケースでも正しい URL が生成されます。
---
permalink: /sitemap.xml
layout: false
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{%- for entry in collections.sitemap %}
<url>
<loc>{{ entry.path | htmlBaseUrl(siteMetadata.url) }}</loc>
{%- if entry.lastmod %}
<lastmod>{{ entry.lastmod }}</lastmod>
{%- endif %}
</url>
{%- endfor %}
</urlset>
robots.txt.njk はシンプルに全クローラを許可し、先ほど生成した sitemap.xml の絶対 URL を宣言します。eleventyExcludeFromCollections: true によりコレクション対象外とし、余計なインデックス対象にならないようにしています。
---
permalink: /robots.txt
layout: false
eleventyExcludeFromCollections: true
---
User-agent: *
Allow: /
Sitemap: {{ "/sitemap.xml" | htmlBaseUrl(siteMetadata.url) }}
設計判断
ビルド時に動的生成 する方針が採用され、静的ファイルとしてリポジトリに配置する代わりに Eleventy のレンダリングプロセスで出力します。これによりビルド環境やデプロイ先が変わっても常に最新の URL リストが反映され、手動管理のリスクが排除されました。HtmlBasePlugin を組み込むことで URL の絶対化ロジックをプラグイン側に委譲し、テンプレート側はシンプルにフィルタ呼び出しだけで済む設計となっています。
また、公開対象の絞り込み をコレクション段階で行うことで、robots.txt に不要なパスが含まれないように保証しています。特に認証が必要なアカウント関連ページは account ディレクトリのソースパスで判定し、許可リストに入っていないファイルは除外するロジックが追加されました。これにより SEO に悪影響を与える可能性のある内部ページがサーチエンジンにインデックスされるリスクが低減します。
まとめ
この PR は Eleventy ビルドに sitemap.xml と robots.txt の自動生成を組み込み、SEO 必須のファイルが常に最新かつ正確に配布されるようにした変更です。コレクションフィルタで公開対象を明示的に絞り、HtmlBasePlugin による絶対 URL 化を活用することで、ビルドプロセスと設定の一貫性を保ちながら運用コストを削減しました。