mirror of
https://github.com/svemagie/blog-eleventy-indiekit.git
synced 2026-05-15 06:58:50 +02:00
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.
This commit is contained in:
@@ -12,10 +12,11 @@
|
|||||||
{% set _bookmarkedUrl = _prevPost.data.bookmarkOf or _prevPost.data.bookmark_of %}
|
{% set _bookmarkedUrl = _prevPost.data.bookmarkOf or _prevPost.data.bookmark_of %}
|
||||||
{% set _repostedUrl = _prevPost.data.repostOf or _prevPost.data.repost_of %}
|
{% set _repostedUrl = _prevPost.data.repostOf or _prevPost.data.repost_of %}
|
||||||
{% set _replyToUrl = _prevPost.data.inReplyTo or _prevPost.data.in_reply_to %}
|
{% 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 %}
|
||||||
<a href="{{ _prevPost.url }}" class="group flex items-start gap-3 text-sm text-primary-600 dark:text-primary-400 hover:underline">
|
<a href="{{ _prevPost.url }}" class="group flex items-start gap-3 text-sm text-primary-600 dark:text-primary-400 hover:underline">
|
||||||
{% if _prevHasOg %}
|
{% if _prevHasOg %}
|
||||||
<img src="/og/{{ _prevPost.fileSlug }}.png" alt="" class="w-20 h-[42px] object-cover rounded flex-shrink-0 opacity-80 group-hover:opacity-100 transition-opacity" loading="lazy" eleventy:ignore>
|
<img src="/og/{{ _prevOgSlug }}.png" alt="" class="w-20 h-[42px] object-cover rounded flex-shrink-0 opacity-80 group-hover:opacity-100 transition-opacity" loading="lazy" eleventy:ignore>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="line-clamp-2 flex items-center gap-1.5">
|
<span class="line-clamp-2 flex items-center gap-1.5">
|
||||||
{% if _likedUrl %}
|
{% if _likedUrl %}
|
||||||
@@ -46,7 +47,8 @@
|
|||||||
{% set _bookmarkedUrl = _nextPost.data.bookmarkOf or _nextPost.data.bookmark_of %}
|
{% set _bookmarkedUrl = _nextPost.data.bookmarkOf or _nextPost.data.bookmark_of %}
|
||||||
{% set _repostedUrl = _nextPost.data.repostOf or _nextPost.data.repost_of %}
|
{% set _repostedUrl = _nextPost.data.repostOf or _nextPost.data.repost_of %}
|
||||||
{% set _replyToUrl = _nextPost.data.inReplyTo or _nextPost.data.in_reply_to %}
|
{% 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 %}
|
||||||
<a href="{{ _nextPost.url }}" class="group flex items-start gap-3 text-sm text-primary-600 dark:text-primary-400 hover:underline {% if _prevPost %}justify-end{% endif %}">
|
<a href="{{ _nextPost.url }}" class="group flex items-start gap-3 text-sm text-primary-600 dark:text-primary-400 hover:underline {% if _prevPost %}justify-end{% endif %}">
|
||||||
<span class="line-clamp-2 flex items-center gap-1.5 {% if _prevPost %}justify-end{% endif %}">
|
<span class="line-clamp-2 flex items-center gap-1.5 {% if _prevPost %}justify-end{% endif %}">
|
||||||
{% if _likedUrl %}
|
{% if _likedUrl %}
|
||||||
@@ -66,7 +68,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
{% if _nextHasOg %}
|
{% if _nextHasOg %}
|
||||||
<img src="/og/{{ _nextPost.fileSlug }}.png" alt="" class="w-20 h-[42px] object-cover rounded flex-shrink-0 opacity-80 group-hover:opacity-100 transition-opacity" loading="lazy" eleventy:ignore>
|
<img src="/og/{{ _nextOgSlug }}.png" alt="" class="w-20 h-[42px] object-cover rounded flex-shrink-0 opacity-80 group-hover:opacity-100 transition-opacity" loading="lazy" eleventy:ignore>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,7 +23,8 @@
|
|||||||
<meta property="og:type" content="{% if page.url == '/' %}website{% else %}article{% endif %}">
|
<meta property="og:type" content="{% if page.url == '/' %}website{% else %}article{% endif %}">
|
||||||
<meta property="og:description" content="{{ ogDesc }}">
|
<meta property="og:description" content="{{ ogDesc }}">
|
||||||
<meta name="description" content="{{ ogDesc }}">
|
<meta name="description" content="{{ ogDesc }}">
|
||||||
{% set hasGeneratedOg = page.fileSlug | hasOgImage %}
|
{% set ogFileSlug = page.url | ogSlug %}
|
||||||
|
{% set hasGeneratedOg = ogFileSlug | hasOgImage %}
|
||||||
{% if ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10 %}
|
{% 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 %}">
|
<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 %}
|
{% elif image and image != "" and (image | length) > 10 %}
|
||||||
@@ -31,7 +32,7 @@
|
|||||||
{% elif contentImage and contentImage != "" and (contentImage | length) > 10 %}
|
{% 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 %}">
|
<meta property="og:image" content="{% if 'http' in contentImage %}{{ contentImage }}{% else %}{{ site.url }}{% if contentImage[0] != '/' %}/{% endif %}{{ contentImage }}{% endif %}">
|
||||||
{% elif hasGeneratedOg %}
|
{% elif hasGeneratedOg %}
|
||||||
<meta property="og:image" content="{{ site.url }}/og/{{ page.fileSlug }}.png">
|
<meta property="og:image" content="{{ site.url }}/og/{{ ogFileSlug }}.png">
|
||||||
{% else %}
|
{% else %}
|
||||||
<meta property="og:image" content="{{ site.url }}/images/og-default.png">
|
<meta property="og:image" content="{{ site.url }}/images/og-default.png">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
{% elif contentImage and contentImage != "" and (contentImage | length) > 10 %}
|
{% elif contentImage and contentImage != "" and (contentImage | length) > 10 %}
|
||||||
<meta name="twitter:image" content="{% if 'http' in contentImage %}{{ contentImage }}{% else %}{{ site.url }}/{{ contentImage }}{% endif %}">
|
<meta name="twitter:image" content="{% if 'http' in contentImage %}{{ contentImage }}{% else %}{{ site.url }}/{{ contentImage }}{% endif %}">
|
||||||
{% elif hasGeneratedOg %}
|
{% elif hasGeneratedOg %}
|
||||||
<meta name="twitter:image" content="{{ site.url }}/og/{{ page.fileSlug }}.png">
|
<meta name="twitter:image" content="{{ site.url }}/og/{{ ogFileSlug }}.png">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# Favicon #}
|
{# Favicon #}
|
||||||
|
|||||||
+12
-4
@@ -362,10 +362,18 @@ export default function (eleventyConfig) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if a generated OG image exists for this page slug
|
// Derive OG slug from page.url (reliable) instead of page.fileSlug
|
||||||
eleventyConfig.addFilter("hasOgImage", (fileSlug) => {
|
// (which suffers from Nunjucks race conditions in Eleventy 3.x parallel rendering)
|
||||||
if (!fileSlug) return false;
|
eleventyConfig.addFilter("ogSlug", (url) => {
|
||||||
const ogPath = resolve(__dirname, ".cache", "og", `${fileSlug}.png`);
|
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);
|
return existsSync(ogPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user