From 8d800e2c2872464b1ee96b2f7548f8f6011ea58f Mon Sep 17 00:00:00 2001 From: Ricardo Date: Wed, 18 Feb 2026 16:48:11 +0100 Subject: [PATCH] fix: derive OG slug from page.url to avoid Nunjucks race condition page.fileSlug suffers from a race condition in Eleventy 3.x parallel rendering where Nunjucks shares state across template compilations, causing slugs to get mixed up between pages. page.url is always correct, so derive the OG slug from it instead. --- _includes/components/post-navigation.njk | 10 ++++++---- _includes/layouts/base.njk | 7 ++++--- eleventy.config.js | 16 ++++++++++++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/_includes/components/post-navigation.njk b/_includes/components/post-navigation.njk index 42d35eb..8de0dbe 100644 --- a/_includes/components/post-navigation.njk +++ b/_includes/components/post-navigation.njk @@ -12,10 +12,11 @@ {% set _bookmarkedUrl = _prevPost.data.bookmarkOf or _prevPost.data.bookmark_of %} {% set _repostedUrl = _prevPost.data.repostOf or _prevPost.data.repost_of %} {% set _replyToUrl = _prevPost.data.inReplyTo or _prevPost.data.in_reply_to %} - {% set _prevHasOg = _prevPost.fileSlug | hasOgImage %} + {% set _prevOgSlug = _prevPost.url | ogSlug %} + {% set _prevHasOg = _prevOgSlug | hasOgImage %} {% if _prevHasOg %} - + {% endif %} {% if _likedUrl %} @@ -46,7 +47,8 @@ {% set _bookmarkedUrl = _nextPost.data.bookmarkOf or _nextPost.data.bookmark_of %} {% set _repostedUrl = _nextPost.data.repostOf or _nextPost.data.repost_of %} {% set _replyToUrl = _nextPost.data.inReplyTo or _nextPost.data.in_reply_to %} - {% set _nextHasOg = _nextPost.fileSlug | hasOgImage %} + {% set _nextOgSlug = _nextPost.url | ogSlug %} + {% set _nextHasOg = _nextOgSlug | hasOgImage %} {% if _likedUrl %} @@ -66,7 +68,7 @@ {% endif %} {% if _nextHasOg %} - + {% endif %} diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 70ac985..e6d009c 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -23,7 +23,8 @@ - {% set hasGeneratedOg = page.fileSlug | hasOgImage %} + {% set ogFileSlug = page.url | ogSlug %} + {% set hasGeneratedOg = ogFileSlug | hasOgImage %} {% if ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10 %} {% elif image and image != "" and (image | length) > 10 %} @@ -31,7 +32,7 @@ {% elif contentImage and contentImage != "" and (contentImage | length) > 10 %} {% elif hasGeneratedOg %} - + {% else %} {% endif %} @@ -51,7 +52,7 @@ {% elif contentImage and contentImage != "" and (contentImage | length) > 10 %} {% elif hasGeneratedOg %} - + {% endif %} {# Favicon #} diff --git a/eleventy.config.js b/eleventy.config.js index 223a01e..5d8c3af 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -362,10 +362,18 @@ export default function (eleventyConfig) { } }); - // Check if a generated OG image exists for this page slug - eleventyConfig.addFilter("hasOgImage", (fileSlug) => { - if (!fileSlug) return false; - const ogPath = resolve(__dirname, ".cache", "og", `${fileSlug}.png`); + // Derive OG slug from page.url (reliable) instead of page.fileSlug + // (which suffers from Nunjucks race conditions in Eleventy 3.x parallel rendering) + eleventyConfig.addFilter("ogSlug", (url) => { + if (!url) return ""; + const last = url.replace(/\/$/, "").split("/").pop(); + return last.replace(/^\d{4}-\d{2}-\d{2}-/, ""); + }); + + // Check if a generated OG image exists for this slug + eleventyConfig.addFilter("hasOgImage", (slug) => { + if (!slug) return false; + const ogPath = resolve(__dirname, ".cache", "og", `${slug}.png`); return existsSync(ogPath); });