Skip to content

Consider replacing the post-build media link processing in out/ with an in-build remark plugin #2219

Description

@novusnota

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.

Metadata

Metadata

Assignees

Labels

scope: ci/cdGitHub Actions (.github), related scripts, commit/push hooks (.husky)scope: linksAll link and redirect checks in CI, and related problems

Type

No fields configured for Spike.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions