fix: use eleventyComputed for OG slug to avoid Nunjucks race condition

Eleventy 3.x renders Nunjucks templates in parallel, causing page.url
to return wrong values in {% set %} tags. This caused OG images to be
mismatched between pages (e.g., bookmark showed note's OG image).

Move ogSlug and hasOgImage computation to eleventyComputed, which runs
during the sequential data cascade phase before parallel rendering.
The computed values are then available as plain template variables.

Refs: https://github.com/11ty/eleventy/issues/3183
This commit is contained in:
Ricardo
2026-02-18 17:17:30 +01:00
parent b065dbfed7
commit 2ebe63ffff
2 changed files with 39 additions and 7 deletions

View File

@@ -23,16 +23,15 @@
<meta property="og:type" content="{% if page.url == '/' %}website{% else %}article{% endif %}">
<meta property="og:description" content="{{ ogDesc }}">
<meta name="description" content="{{ ogDesc }}">
{% set ogFileSlug = page.url | ogSlug %}
{% set hasGeneratedOg = ogFileSlug | hasOgImage %}
{# ogSlug and hasOgImage are pre-computed via eleventyComputed (race-condition safe) #}
{% if ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10 %}
<meta property="og:image" content="{% if 'http' in ogPhoto %}{{ ogPhoto }}{% else %}{{ site.url }}{% if ogPhoto[0] != '/' %}/{% endif %}{{ ogPhoto }}{% endif %}">
{% elif image and image != "" and (image | length) > 10 %}
<meta property="og:image" content="{% if 'http' in image %}{{ image }}{% else %}{{ site.url }}{% if image[0] != '/' %}/{% endif %}{{ image }}{% endif %}">
{% elif contentImage and contentImage != "" and (contentImage | length) > 10 %}
<meta property="og:image" content="{% if 'http' in contentImage %}{{ contentImage }}{% else %}{{ site.url }}{% if contentImage[0] != '/' %}/{% endif %}{{ contentImage }}{% endif %}">
{% elif hasGeneratedOg %}
<meta property="og:image" content="{{ site.url }}/og/{{ ogFileSlug }}.png">
{% elif hasOgImage %}
<meta property="og:image" content="{{ site.url }}/og/{{ ogSlug }}.png">
{% else %}
<meta property="og:image" content="{{ site.url }}/images/og-default.png">
{% endif %}
@@ -41,7 +40,7 @@
<meta property="og:locale" content="{{ site.locale | default('en_US') }}">
{# Twitter Card meta tags #}
{% set hasImage = hasGeneratedOg or (ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10) or (image and image != "" and (image | length) > 10) or (contentImage and contentImage != "" and (contentImage | length) > 10) %}
{% set hasImage = hasOgImage or (ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10) or (image and image != "" and (image | length) > 10) or (contentImage and contentImage != "" and (contentImage | length) > 10) %}
<meta name="twitter:card" content="{% if hasImage %}summary_large_image{% else %}summary{% endif %}">
<meta name="twitter:title" content="{{ ogTitle }}">
<meta name="twitter:description" content="{{ ogDesc }}">
@@ -51,8 +50,8 @@
<meta name="twitter:image" content="{% if 'http' in image %}{{ image }}{% else %}{{ site.url }}/{{ image }}{% endif %}">
{% elif contentImage and contentImage != "" and (contentImage | length) > 10 %}
<meta name="twitter:image" content="{% if 'http' in contentImage %}{{ contentImage }}{% else %}{{ site.url }}/{{ contentImage }}{% endif %}">
{% elif hasGeneratedOg %}
<meta name="twitter:image" content="{{ site.url }}/og/{{ ogFileSlug }}.png">
{% elif hasOgImage %}
<meta name="twitter:image" content="{{ site.url }}/og/{{ ogSlug }}.png">
{% endif %}
{# Favicon #}