mirror of
https://github.com/svemagie/blog-eleventy-indiekit.git
synced 2026-05-15 06:58:50 +02:00
fix: derive ogSlug from inputPath to fix Eleventy 3.x race condition
page.url in eleventyComputed returns URLs from other pages being processed concurrently in Eleventy 3.x parallel rendering. This caused OG images to show wrong post types and titles (e.g., a note showing "Reply" badge from a completely different post). Fix: use page.inputPath (physical file path) which is always correct, matching the approach already used by the permalink computation.
This commit is contained in:
+31
-19
@@ -1,10 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* Computed data resolved during the data cascade (sequential, per-page).
|
* Computed data resolved during the data cascade.
|
||||||
*
|
*
|
||||||
* Eleventy 3.x renders Nunjucks templates in parallel, which causes
|
* Eleventy 3.x parallel rendering causes `page.url` and `page.fileSlug`
|
||||||
* `page.url` and `page.fileSlug` to return wrong values when read
|
* to return values from OTHER pages being processed concurrently.
|
||||||
* via {% set %} in templates. By computing OG-related values here,
|
* This affects both templates and eleventyComputed functions.
|
||||||
* they are resolved before parallel rendering begins.
|
*
|
||||||
|
* Fix: ALL computed values derive from `page.inputPath` (the physical file
|
||||||
|
* path on disk), which is always correct regardless of parallel rendering.
|
||||||
|
* NEVER use `page.url` or `page.fileSlug` here.
|
||||||
*
|
*
|
||||||
* See: https://github.com/11ty/eleventy/issues/3183
|
* See: https://github.com/11ty/eleventy/issues/3183
|
||||||
*/
|
*/
|
||||||
@@ -47,30 +50,39 @@ export default {
|
|||||||
return data.permalink;
|
return data.permalink;
|
||||||
},
|
},
|
||||||
|
|
||||||
// OG image slug — must reconstruct date-prefixed filename from URL segments.
|
// OG image slug — derive from inputPath (physical file), NOT page.url.
|
||||||
|
// page.url suffers from Eleventy 3.x parallel rendering race conditions
|
||||||
|
// where it can return the URL of a DIFFERENT page being processed concurrently.
|
||||||
|
// inputPath is the physical file path, which is always correct.
|
||||||
// OG images are generated as {yyyy}-{MM}-{dd}-{slug}.png by lib/og.js.
|
// OG images are generated as {yyyy}-{MM}-{dd}-{slug}.png by lib/og.js.
|
||||||
// With new URL structure /type/yyyy/MM/dd/slug/, we reconstruct the filename.
|
|
||||||
ogSlug: (data) => {
|
ogSlug: (data) => {
|
||||||
const url = data.page?.url || "";
|
const inputPath = data.page?.inputPath || "";
|
||||||
const segments = url.split("/").filter(Boolean);
|
const match = inputPath.match(
|
||||||
// Date-based URL: /type/yyyy/MM/dd/slug/ → 5 segments
|
/content\/([^/]+)\/(\d{4})-(\d{2})-(\d{2})-(.+)\.md$/,
|
||||||
if (segments.length === 5) {
|
);
|
||||||
const [, year, month, day, slug] = segments;
|
if (match) {
|
||||||
|
const [, , year, month, day, slug] = match;
|
||||||
return `${year}-${month}-${day}-${slug}`;
|
return `${year}-${month}-${day}-${slug}`;
|
||||||
}
|
}
|
||||||
// Fallback: last segment (for pages, legacy URLs)
|
// Fallback for pages/root files: use last path segment
|
||||||
return segments[segments.length - 1] || "";
|
const segments = inputPath.split("/").filter(Boolean);
|
||||||
|
const last = segments[segments.length - 1] || "";
|
||||||
|
return last.replace(/\.md$/, "");
|
||||||
},
|
},
|
||||||
|
|
||||||
hasOgImage: (data) => {
|
hasOgImage: (data) => {
|
||||||
const url = data.page?.url || "";
|
const inputPath = data.page?.inputPath || "";
|
||||||
const segments = url.split("/").filter(Boolean);
|
const match = inputPath.match(
|
||||||
|
/content\/([^/]+)\/(\d{4})-(\d{2})-(\d{2})-(.+)\.md$/,
|
||||||
|
);
|
||||||
let slug;
|
let slug;
|
||||||
if (segments.length === 5) {
|
if (match) {
|
||||||
const [, year, month, day, s] = segments;
|
const [, , year, month, day, s] = match;
|
||||||
slug = `${year}-${month}-${day}-${s}`;
|
slug = `${year}-${month}-${day}-${s}`;
|
||||||
} else {
|
} else {
|
||||||
slug = segments[segments.length - 1] || "";
|
const segments = inputPath.split("/").filter(Boolean);
|
||||||
|
const last = segments[segments.length - 1] || "";
|
||||||
|
slug = last.replace(/\.md$/, "");
|
||||||
}
|
}
|
||||||
if (!slug) return false;
|
if (!slug) return false;
|
||||||
const ogPath = resolve(__dirname, "..", ".cache", "og", `${slug}.png`);
|
const ogPath = resolve(__dirname, "..", ".cache", "og", `${slug}.png`);
|
||||||
|
|||||||
Reference in New Issue
Block a user