用途
本技能用于在 React 应用中渲染 Markdown。目标是把 Markdown 源码或已解析的 MarkdownDocument 渲染为 React 组件,而不是注入 HTML 字符串,从而保留 React 组件替换能力并避免额外的可信 HTML 边界。
该技能建立在 render-markdown 之上。使用前应先阅读 render-markdown,了解共享的语法配置、解析器选项、AST 行为和核心信任边界。
主要能力
- 直接渲染 Markdown 源码,并由应用保留外围语义元素。
Markdown返回一个 React fragment。React 适配器要求 React 18 或更高版本。 - 通过
components将生成的标签替换为应用自己的组件(如用自定义组件替换a标签)。已知内置标签会推断出匹配的 React props;任意的扩展组件标签名同样受支持。 - 先解析再重复渲染:用 parser 生成 MarkdownDocument,再交给
Markdown渲染,适合缓存 AST 的场景。解析器选项和文档转换需在创建 document 时应用,渲染器选项无法反向改变其结构。 - 服务端静态渲染:配合
react-dom/server的renderToStaticMarkup输出静态 React 标记。核心静态输出经过与renderHtml()的结构等价性测试。 - 低层节点 API:使用
renderMarkdownReact渲染已解析文档;仅在需要按单个公开 AST 节点自定义树组合时使用renderBlockReact或renderInlineReact。
使用方式
基本用法:从 @tanstack/markdown/react 引入 Markdown,将 source 作为子元素渲染。
组件替换:通过 MarkdownComponents 类型的 components 映射,按生成的标签名(如 a)而非 AST 判别名(如 link)进行替换。
先解析后渲染:从 @tanstack/markdown/parser 引入 parseMarkdown 得到 document,再传给 Markdown。
服务端渲染:从 react-dom/server 引入 renderToStaticMarkup,包裹含 Markdown 的组件树。
低层组合:从解析器得到 document 后,用 renderMarkdownReact(document) 返回 ReactNode。
适用场景
- 在 React 18+ 应用中渲染文章、文档等 Markdown 内容,同时希望用自定义 React 组件替换链接等元素。
- 需要在服务端生成静态 React 标记的场景。
- 需要先缓存解析结果、后续重复渲染同一文档的场景。
- 需要通过 ComponentNode 与扩展机制输出可移植自定义标签,并由 React 通过 components 替换的场景。
限制与注意事项
- React 适配器要求 React 18 或更高版本。
- 不要用 HTML 字符串路径渲染:
renderHtml配合dangerouslySetInnerHTML会绕过 React 组件替换,并产生不必要的可信 HTML 边界。 components映射以生成的标签名(如a)为键,而非 AST 判别名(如link)。MarkdownExtension.renderHtml是 HTML 专用的;在 React 中实现可移植的自定义输出应使用 ComponentNode 并配合按生成标签名映射的组件。可参考 custom-extensions 了解 ComponentNode 输出。- 安全关键项:不要对不受信任的输入启用
allowHtml。启用后 React 会使用dangerouslySetInnerHTML,而 TanStack Markdown 不会对该原始 HTML 进行净化。 - 渲染器一致性与 React 自定义之间存在张力:核心 React SSR 经过与
renderHtml()的等价性测试,但 React 组件替换、原始 HTML、高亮器输出以及仅 HTML 的扩展钩子属于应用控制的边界,不在该一致性保证范围内。 - 生产环境应审计原始 HTML、高亮器输出、不受信任内容和 SSR 边界(参见 production-pipelines)。
- 本资料未提供收费、价格或平台相关信息。
交叉引用
- render-markdown:共享的 MarkdownInput、解析器选项、AST 行为与语法配置。
- custom-extensions:生成可被 React 通过 components 替换的自定义标签。
- production-pipelines:审计原始 HTML、高亮器输出、不受信任内容和 SSR 边界。