From 14081c9f65617b51ed923e84ac22515b35e97824 Mon Sep 17 00:00:00 2001 From: Herrtian <70463940+Herrtian@users.noreply.github.com> Date: Wed, 27 May 2026 13:54:54 +0200 Subject: [PATCH 1/2] fix(web): use base URL for synthetic page assets --- .../web/utils/__tests__/processing.test.mjs | 29 ++++++++++++++++++- src/generators/web/utils/processing.mjs | 18 +++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/generators/web/utils/__tests__/processing.test.mjs b/src/generators/web/utils/__tests__/processing.test.mjs index afbc64c3..a7807684 100644 --- a/src/generators/web/utils/__tests__/processing.test.mjs +++ b/src/generators/web/utils/__tests__/processing.test.mjs @@ -1,7 +1,19 @@ import assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { populateWithEvaluation } from '../processing.mjs'; +import { setConfig } from '../../../../utils/configuration/index.mjs'; +import { populateWithEvaluation, resolvePageRoot } from '../processing.mjs'; + +await setConfig({ + version: 'v22.0.0', + changelog: [], + generators: { + web: { + useAbsoluteURLs: false, + baseURL: 'https://nodejs.org/docs', + }, + }, +}); describe('populateWithEvaluation', () => { it('substitutes simple ${variable} placeholders', () => { @@ -61,3 +73,18 @@ describe('populateWithEvaluation', () => { assert.strictEqual(result, 'count: 42'); }); }); + +describe('resolvePageRoot', () => { + it('keeps relative roots for regular pages', () => { + const result = resolvePageRoot({ path: '/api/fs' }); + assert.strictEqual(result, '../'); + }); + + it('uses the configured base URL for synthetic pages', () => { + const result = resolvePageRoot({ + path: '/404', + synthetic: true, + }); + assert.strictEqual(result, 'https://nodejs.org/docs/'); + }); +}); diff --git a/src/generators/web/utils/processing.mjs b/src/generators/web/utils/processing.mjs index 5b528ff5..3c5b7b0e 100644 --- a/src/generators/web/utils/processing.mjs +++ b/src/generators/web/utils/processing.mjs @@ -31,6 +31,19 @@ export const populateWithEvaluation = (template, config) => { return fn(...values); }; +/** + * @param {import('../../metadata/types').MetadataEntry} data + * @returns {string} + */ +export const resolvePageRoot = data => { + if (data.synthetic === true) { + return String(getConfig('web').baseURL).replace(/\/?$/, '/'); + } + + const unresolvedRoot = relativeOrAbsolute('/', data.path); + return unresolvedRoot.endsWith('/') ? unresolvedRoot : `${unresolvedRoot}/`; +}; + /** * Converts JSX AST entries to server and client JavaScript code. * @@ -131,10 +144,7 @@ export async function processJSXEntries( // Step 3: Render final HTML pages const results = await Promise.all( entries.map(async ({ data }) => { - const unresolvedRoot = relativeOrAbsolute('/', data.path); - const root = unresolvedRoot.endsWith('/') - ? unresolvedRoot - : `${unresolvedRoot}/`; + const root = resolvePageRoot(data); // Replace template placeholders with actual content const renderedHtml = populateWithEvaluation(template, { From ba42722deb009508d4ab9b540623c15f0fc09806 Mon Sep 17 00:00:00 2001 From: Herrtian <70463940+Herrtian@users.noreply.github.com> Date: Wed, 27 May 2026 14:43:34 +0200 Subject: [PATCH 2/2] Fix synthetic page preview assets --- .../web/utils/__tests__/processing.test.mjs | 19 +++++++++++++++++-- src/generators/web/utils/processing.mjs | 3 ++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/generators/web/utils/__tests__/processing.test.mjs b/src/generators/web/utils/__tests__/processing.test.mjs index a7807684..c2aa4469 100644 --- a/src/generators/web/utils/__tests__/processing.test.mjs +++ b/src/generators/web/utils/__tests__/processing.test.mjs @@ -1,7 +1,10 @@ import assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { setConfig } from '../../../../utils/configuration/index.mjs'; +import { + default as getConfig, + setConfig, +} from '../../../../utils/configuration/index.mjs'; import { populateWithEvaluation, resolvePageRoot } from '../processing.mjs'; await setConfig({ @@ -80,11 +83,23 @@ describe('resolvePageRoot', () => { assert.strictEqual(result, '../'); }); - it('uses the configured base URL for synthetic pages', () => { + it('uses the server root for synthetic pages', () => { + const result = resolvePageRoot({ + path: '/404', + synthetic: true, + }); + assert.strictEqual(result, '/'); + }); + + it('uses the configured base URL for synthetic pages with absolute URLs', async () => { + getConfig('web').useAbsoluteURLs = true; + const result = resolvePageRoot({ path: '/404', synthetic: true, }); assert.strictEqual(result, 'https://nodejs.org/docs/'); + + getConfig('web').useAbsoluteURLs = false; }); }); diff --git a/src/generators/web/utils/processing.mjs b/src/generators/web/utils/processing.mjs index 3c5b7b0e..d09191b6 100644 --- a/src/generators/web/utils/processing.mjs +++ b/src/generators/web/utils/processing.mjs @@ -37,7 +37,8 @@ export const populateWithEvaluation = (template, config) => { */ export const resolvePageRoot = data => { if (data.synthetic === true) { - return String(getConfig('web').baseURL).replace(/\/?$/, '/'); + const { baseURL, useAbsoluteURLs } = getConfig('web'); + return useAbsoluteURLs ? String(baseURL).replace(/\/?$/, '/') : '/'; } const unresolvedRoot = relativeOrAbsolute('/', data.path);