The current approach works, yet it is a bit brittle.
Alternative approach, to be placed after remarkTabs and before ...v (or, actually, after all other remark plugins, idk):
// NOTE: prefix root-relative media URLs with the GitHub Pages basePath.
// Next.js auto-prefixes next/link and static-import next/image only,
// NOT raw <img>/<video>/<Image> string srcs — so we do it here.
function remarkAssetBasePath() {
const base = process.env.NEXT_PUBLIC_BASE_PATH ?? '';
if (!base) return () => { }; // no-op when basePath is empty (local/Vercel)
const ELEMS = new Set(['img', 'Image', 'video', 'source']);
const ATTRS = new Set(['src', 'darkSrc', 'poster']);
const assetRe = /^\/(?:images|logo|pdfs|tvm|videos)\//; return (tree: any) => {
visitParents(tree, (node: any) => {
if (node.type !== 'mdxJsxFlowElement' && node.type !== 'mdxJsxTextElement') return;
if (!ELEMS.has(node.name)) return;
for (const attr of node.attributes ?? []) {
if (attr.type !== 'mdxJsxAttribute' || !ATTRS.has(attr.name)) continue;
if (typeof attr.value === 'string' && assetRe.test(attr.value)) {
attr.value = base + attr.value; // string only ⇒ skips {expr} static imports
}
}
});
};
},
- href is intentionally excluded — prefixing href here would double them, and /tvm/... is also a doc-route namespace, not only an asset dir.
- This also fixes the serialized RSC props embedded in the HTML (the old doubleQuoteAttrPattern/specAttrPattern cases), since those are the same prop values.
The current approach works, yet it is a bit brittle.
Alternative approach, to be placed after
remarkTabsand before...v(or, actually, after all other remark plugins, idk):