@@ -20,17 +20,39 @@ export const docs = defineDocs({
2020} ) ;
2121
2222// Rehype plugin that prepends basePath to local <img src="/..."> paths.
23- // Raw HTML <img> tags in MDX bypass the mdx-components.tsx `img` override and are
24- // emitted as literal HTML, so Next.js never gets a chance to apply basePath automatically.
25- // We rewrite them here at MDX compile time instead .
23+ // In MDX, <img> tags are parsed as JSX (mdxJsxFlowElement / mdxJsxTextElement),
24+ // NOT as rehype `element` nodes. Their attributes live in node.attributes[],
25+ // not node.properties — so we must handle both node types .
2626function rehypePrependBasePath ( ) {
2727 const basePath =
2828 process . env . NEXT_PUBLIC_BASE_PATH ||
2929 ( process . env . NODE_ENV === 'production' ? '/plugins-doc-site' : '' ) ;
30-
30+
3131 if ( ! basePath ) return ( tree : any ) => tree ;
3232
3333 function walk ( node : any ) {
34+ // MDX JSX nodes: mdxJsxFlowElement / mdxJsxTextElement
35+ if (
36+ ( node . type === 'mdxJsxFlowElement' || node . type === 'mdxJsxTextElement' ) &&
37+ node . name === 'img' &&
38+ Array . isArray ( node . attributes )
39+ ) {
40+ for ( const attr of node . attributes ) {
41+ if (
42+ attr . type === 'mdxJsxAttribute' &&
43+ attr . name === 'src' &&
44+ typeof attr . value === 'string'
45+ ) {
46+ const src : string = attr . value ;
47+ if ( src . startsWith ( '/' ) && ! src . startsWith ( '//' ) && ! src . startsWith ( basePath ) ) {
48+ attr . value = basePath + src ;
49+ console . debug ( 'MDX img src after basePath:' , attr . value ) ;
50+ }
51+ }
52+ }
53+ }
54+
55+ // Standard rehype element nodes (fallback)
3456 if (
3557 node . type === 'element' &&
3658 node . tagName === 'img' &&
@@ -41,6 +63,7 @@ function rehypePrependBasePath() {
4163 node . properties . src = basePath + src ;
4264 }
4365 }
66+
4467 if ( Array . isArray ( node . children ) ) {
4568 for ( const child of node . children ) walk ( child ) ;
4669 }
0 commit comments