From 7f26d7398bce484eef01ecb0ee32fbad979cdaf3 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Sun, 29 Mar 2026 11:05:42 +0200 Subject: [PATCH] fix: generate sitemap.xml in eleventy.after hook instead of template The @quasibit/eleventy-plugin-sitemap shortcode triggers TemplateContentPrematureUseError on paginated templates in Eleventy 3.x. Move sitemap generation to eleventy.after hook which scans the output directory for index.html files after all templates are rendered. Remove the plugin import/registration and the sitemap.njk template. --- eleventy.config.js | 79 ++++++++++++++++++++++++++++------------------ sitemap.njk | 7 ---- 2 files changed, 49 insertions(+), 37 deletions(-) delete mode 100644 sitemap.njk diff --git a/eleventy.config.js b/eleventy.config.js index 1528871..f844ff5 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -2,7 +2,7 @@ import pluginWebmentions from "@chrisburnell/eleventy-cache-webmentions"; import pluginRss from "@11ty/eleventy-plugin-rss"; import embedEverything from "eleventy-plugin-embed-everything"; import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"; -import sitemap from "@quasibit/eleventy-plugin-sitemap"; + import markdownIt from "markdown-it"; import markdownItAnchor from "markdown-it-anchor"; import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; @@ -352,12 +352,6 @@ export default function (eleventyConfig) { return eleventyConfig.htmlTransformer.transformContent(this.outputPath, content, this); }); - // Sitemap generation - eleventyConfig.addPlugin(sitemap, { - sitemap: { - hostname: siteUrl, - }, - }); // Wrap elements in for responsive tables eleventyConfig.addTransform("table-saw-wrap", function (content, outputPath) { @@ -674,29 +668,6 @@ export default function (eleventyConfig) { }); }); - // Exclude pages from sitemap by URL pattern - // Usage: collections.all | excludeFromSitemap - eleventyConfig.addFilter("excludeFromSitemap", (items) => { - const excludePatterns = [ - /^\/replies\//, - /^\/feed\.(xml|json)$/, - /\/feed\.(xml|json)$/, - /^\/categories\//, - /^\/digest/, - /^\/webmention-debug\//, - /^\/404\.html$/, - /^\/sitemap\.xml$/, - /^\/dashboard/, - /^\/homepage/, - /^\/search\//, - /^\/graph\//, - ]; - return items.filter((item) => { - const url = item.url || ""; - return !excludePatterns.some((pattern) => pattern.test(url)); - }); - }); - // Slugify filter eleventyConfig.addFilter("slugify", (str) => { if (!str) return ""; @@ -1426,6 +1397,54 @@ export default function (eleventyConfig) { } } + // Sitemap generation — scan output HTML files, exclude URL patterns + if (!incremental) { + const sitemapOutputDir = directories?.output || dir.output; + const excludePatterns = [ + /^\/replies\//, + /\/feed\.(xml|json)$/, + /^\/categories\//, + /^\/digest/, + /^\/webmention-debug\//, + /^\/404\.html$/, + /^\/dashboard/, + /^\/homepage/, + /^\/search\//, + /^\/graph\//, + /^\/sitemap\.xml$/, + ]; + try { + const walkHtml = (base, prefix = "") => { + const entries = []; + for (const entry of readdirSync(resolve(base, prefix), { withFileTypes: true })) { + const rel = prefix ? `${prefix}/${entry.name}` : entry.name; + if (entry.isDirectory()) { + entries.push(...walkHtml(base, rel)); + } else if (entry.name === "index.html") { + const urlPath = prefix ? `/${prefix}/` : "/"; + entries.push(urlPath); + } + } + return entries; + }; + const allUrls = walkHtml(sitemapOutputDir) + .filter((url) => !excludePatterns.some((p) => p.test(url))) + .sort(); + const xmlLines = [ + '', + '', + ]; + for (const url of allUrls) { + xmlLines.push(` ${siteUrl}${url}`); + } + xmlLines.push(""); + writeFileSync(resolve(sitemapOutputDir, "sitemap.xml"), xmlLines.join("\n")); + console.log(`[sitemap] Generated sitemap.xml with ${allUrls.length} URLs`); + } catch (err) { + console.error("[sitemap] Generation failed:", err.message); + } + } + // Pagefind indexing — run exactly once per process lifetime if (!pagefindDone) { pagefindDone = true; diff --git a/sitemap.njk b/sitemap.njk deleted file mode 100644 index 4436965..0000000 --- a/sitemap.njk +++ /dev/null @@ -1,7 +0,0 @@ ---- -permalink: /sitemap.xml -layout: null -eleventyExcludeFromCollections: true ---- -{% set sitemapItems = collections.all | excludeFromSitemap %} -{% sitemap sitemapItems %}