From 1391aa6513da5a6e789a19488e97c97954aa44fd Mon Sep 17 00:00:00 2001 From: Ivan Despot <66276597+g-despot@users.noreply.github.com> Date: Thu, 2 Jul 2026 11:38:53 +0200 Subject: [PATCH] fix(docs): resolve ||site.*|| version tokens in imported _includes partials Version tokens in partials imported from _includes/ (e.g. the Java Maven version in the quickstart install tabs) rendered as the literal ||site.java_client_version|| on 5 pages. Those partials are compiled by Docusaurus' MDX *fallback* loader, which does not receive the docs preset's remarkPlugins, so the remark-replace plugin never ran on them. Route the same ||site.*|| interpolation through the global markdown.preprocessor hook, which runs on every md/mdx file (including fallback-loaded partials), sharing a single implementation (replaceSiteTokens) with the remark plugin. The replacement is idempotent and its regex is narrow, so pages the plugin already handles are unaffected. --- docusaurus.config.js | 10 ++++++++++ src/remark/remark-replace.js | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index 007969d89..0d053915a 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -34,6 +34,16 @@ const config = { onBrokenMarkdownImages: "throw", }, mermaid: true, + // Interpolate ||site.*|| tokens on raw file content, for every md/mdx file. + // The remark-replace plugin below only runs on docs pages; partials imported + // from _includes/ are compiled by Docusaurus' MDX *fallback* loader, which + // does not receive the docs preset's remarkPlugins, so ||site.*|| tokens in + // those partials (e.g. code snippets in the quickstart install tabs) were + // never interpolated. This preprocessor covers every file, including + // fallback-loaded partials. It shares one implementation with the plugin and + // is idempotent, so it does not affect pages the plugin already handles. + preprocessor: ({ fileContent, filePath }) => + remarkReplace.replaceSiteTokens(fileContent, filePath), }, i18n: { diff --git a/src/remark/remark-replace.js b/src/remark/remark-replace.js index 0e09f1574..f377f8217 100644 --- a/src/remark/remark-replace.js +++ b/src/remark/remark-replace.js @@ -15,18 +15,25 @@ const siteConfig = readSiteConfig(); // pattern to match: ||site.some_name|| in markdown const pattern = /[|]{2}[ ]*site\.([a-z_]*)[ ]*[|]{2}/g -const interpolate = (value, vfile) => { +// Shared token replacement. Used by the remark plugin (below) for docs pages, +// and by the site's markdown.preprocessor (docusaurus.config.js) so that the +// same ||site.*|| interpolation also runs on imported partials from _includes/, +// which are compiled by Docusaurus' MDX *fallback* loader and therefore never +// see this remark plugin. Keeping one implementation avoids drift. +const replaceSiteTokens = (value, sourcePath) => { // replace the pattern with config variables return value.replaceAll(pattern, (_, name) => { // display a warning if config variable is missing if (siteConfig[name] == undefined) { - console.warn('\x1b[33m%s', vfile.path, '\x1b[0m'); + console.warn('\x1b[33m%s', sourcePath, '\x1b[0m'); console.warn(`Couldn't find`, '\x1b[31m', `||site.${name}||`, '\x1b[0m'); } return siteConfig[name] }) } +const interpolate = (value, vfile) => replaceSiteTokens(value, vfile.path) + const valueNodes = ['text', 'jsx', 'code', 'inlineCode']; const valueNodeFilter = (node) => valueNodes.includes(node.type) && // contains one of the types in valueNodes @@ -51,3 +58,6 @@ const plugin = (options) => { }; module.exports = plugin; +// Exposed so docusaurus.config.js `markdown.preprocessor` can reuse the exact +// same interpolation on raw file content (covers fallback-loaded partials). +module.exports.replaceSiteTokens = replaceSiteTokens;