如何将MDX中的动态href传入Next.js自定义Anchor组件
问题
我想通过MDX将Markdown标签里的href数据传递给Next.js的自定义样式组件。希望用户在Markdown里写标准链接语法:
[Website](http://www.website.com)
然后把数据传入这个自定义组件:
// ./components/md/Anchor.tsx function Anchor({ hrefProp, text }) { return <a className="text-blue-600 my-4 text-base" href={hrefProp} target="_blank" rel="noopener">{text}</a>; } export default Anchor;
但目前MDX转JSX时URL http://website.com 丢失了,只能获取到{text}内容。我不想改动Markdown语法,有什么解决办法?我曾考虑用meta或frontmatter传递href数据,但觉得不合适。
解决方案
用MDXProvider覆盖默认组件
这是最直接的方案,MDX允许通过上下文替换默认的HTML标签。首先调整自定义组件的props接收逻辑,适配MDX的默认传递规则:// ./components/md/Anchor.tsx function Anchor({ href, children }) { return <a className="text-blue-600 my-4 text-base" href={href} target="_blank" rel="noopener">{children}</a>; } export default Anchor;然后在渲染MDX的页面/组件中,用
MDXProvider包裹并注册自定义组件:import { MDXProvider } from '@mdx-js/react'; import Anchor from './components/md/Anchor'; const components = { a: Anchor, }; export default function MDXPage({ children }) { return <MDXProvider components={components}>{children}</MDXProvider>; }这样标准Markdown链接会自动被替换为你的自定义组件,
href和文本内容都能正确传递。用rehype插件自定义处理链接节点
若需要更灵活的控制,可编写rehype插件拦截MDX的AST节点,将原生<a>转换为自定义组件:// rehype-custom-links.js import { visit } from 'unist-util-visit'; export default function rehypeCustomLinks() { return (tree) => { visit(tree, 'element', (node) => { if (node.tagName === 'a') { node.type = 'mdxJsxFlowElement'; node.name = 'Anchor'; node.attributes = [ { type: 'mdxJsxAttribute', name: 'hrefProp', value: node.properties.href }, { type: 'mdxJsxAttribute', name: 'text', value: node.children[0].value }, ]; node.children = []; } }); }; }在Next.js的MDX配置文件(如
mdx-components.js或next.config.js)中引入该插件,编译时即可自动将Markdown链接转换为你的Anchor组件,并传递所需props。不建议使用frontmatter/meta传递
这种方式需要将链接单独写在文档头部,和正文的Markdown链接分离,违背了用户直接写标准语法的需求,因此不推荐。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

