streamdown

streamdown

热门

实现、配置与自定义 Streamdown —— 专为流式传输优化的 React Markdown 渲染器,支持语法高亮、Mermaid 图表、数学公式渲染以及中日韩(CJK)文字支持。适用于 Streamdown 的安装配置、插件使用、样式定制、安全设置,以及与 AI 流式输出(如 Vercel AI SDK)的集成。触发场景:(1) 安装或配置 Streamdown;(2) 配置插件(代码高亮、Mermaid、数学公式、CJK);(3) 为 Streamdown 输出配置样式或主题;(4) 集成 AI 对话/流式输出;(5) 配置安全性、链接安全或自定义 HTML 标签;(6) 使用光标(caret)、静态模式或自定义组件;(7) 排查 Tailwind、Shiki 或 Vite 相关问题。

5459Star
278Fork
更新于 2026/7/21
SKILL.md
只读
名称
streamdown
描述

实现、配置与自定义 Streamdown —— 专为流式传输优化的 React Markdown 渲染器,支持语法高亮、Mermaid 图表、数学公式渲染以及中日韩(CJK)文字支持。适用于 Streamdown 的安装配置、插件使用、样式定制、安全设置,以及与 AI 流式输出(如 Vercel AI SDK)的集成。触发场景:(1) 安装或配置 Streamdown;(2) 配置插件(代码高亮、Mermaid、数学公式、CJK);(3) 为 Streamdown 输出配置样式或主题;(4) 集成 AI 对话/流式输出;(5) 配置安全性、链接安全或自定义 HTML 标签;(6) 使用光标(caret)、静态模式或自定义组件;(7) 排查 Tailwind、Shiki 或 Vite 相关问题。

Streamdown

专为流式传输优化的 React Markdown 渲染器。可作为 react-markdown 的开箱即用替代方案,内置流式渲染支持、安全防护与交互控制功能。

快速上手

1. 安装

npm install streamdown

可选插件(按需安装):

npm install @streamdown/code @streamdown/mermaid @streamdown/math @streamdown/cjk

2. 配置 Tailwind CSS(必须)

这是最容易漏掉的一步。 Streamdown 使用 Tailwind 处理样式,必须扫描其 dist 文件。

Tailwind v4 —— 在 globals.css 中添加:

@source "../node_modules/streamdown/dist/*.js";

仅为你已安装的包添加插件的 @source 行(忽略未安装的插件可避免 Tailwind 报错)。参考插件页面获取确切路径:

  • Code: @source "../node_modules/@streamdown/code/dist/*.js";
  • CJK: @source "../node_modules/@streamdown/cjk/dist/*.js";
  • Math: @source "../node_modules/@streamdown/math/dist/*.js";
  • Mermaid: @source "../node_modules/@streamdown/mermaid/dist/*.js";

Tailwind v3 —— 在 tailwind.config.js 中添加:

module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./node_modules/streamdown/dist/*.js",
  ],
};

3. 基础用法

import { Streamdown } from 'streamdown';

<Streamdown>{markdown}</Streamdown>

4. 集成 AI 流式传输(Vercel AI SDK)

'use client';
import { useChat } from '@ai-sdk/react';
import { Streamdown } from 'streamdown';
import { code } from '@streamdown/code';

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat();

  return (
    <>
      {messages.map((msg, i) => (
        <Streamdown
          key={msg.id}
          plugins={{ code }}
          caret="block"
          isAnimating={isLoading && i === messages.length - 1 && msg.role === 'assistant'}
        >
          {msg.content}
        </Streamdown>
      ))}
      <form onSubmit={handleSubmit}>
        <input value={input} onChange={handleInputChange} disabled={isLoading} />
      </form>
    </>
  );
}

5. 静态模式(博客、文档)

<Streamdown mode="static" plugins={{ code }}>
  {content}
</Streamdown>

核心 Prop 列表

Prop 类型 默认值 用途
children string Markdown 内容
mode "streaming" | "static" "streaming" 渲染模式
plugins { code?, mermaid?, math?, cjk? } 功能插件
isAnimating boolean false 流式动画/生成中指示器
caret "block" | "circle" 光标样式
components Components 自定义元素重写
controls boolean | object true 交互按钮
linkSafety LinkSafetyConfig { enabled: true } 链接确认弹窗
shikiTheme [light, dark] ['github-light', 'github-dark'] 代码主题
className string 容器 Class 名
allowedElements string[] 全部 允许的标签名称
disallowedElements string[] [] 禁用/不允许的标签名称
allowElement AllowElement 自定义元素过滤器
unwrapDisallowed boolean false 是否保留被禁用元素的子节点
skipHtml boolean false 是否忽略原生 HTML
urlTransform UrlTransform defaultUrlTransform URL 转换/清理函数

完整 API 参考请查看 references/api.md

插件速查表

插件 软件包 用途
Code @streamdown/code 语法高亮(基于 Shiki,支持 200+ 种语言)
Mermaid @streamdown/mermaid 图表(流程图、时序图等)
Math @streamdown/math 基于 KaTeX 的 LaTeX 数学公式(需引入 CSS)
CJK @streamdown/cjk 中日韩文本优化支持

数学公式插件需要引入 CSS:

import 'katex/dist/katex.min.css';

有关插件配置的详细信息,请参阅 references/plugins.md

参考文档

参考以下文档了解更深入的实现细节:

配置示例

可直接从 assets/examples/ 复制并修改:

常见踩坑点(Gotchas)

  1. Tailwind 样式丢失 —— 请添加 @source 指令或在配置文件中将 node_modules/streamdown/dist/*.js 加入 content
  2. 数学公式无法渲染 —— 记得导入 katex/dist/katex.min.css
  3. 光标(Caret)不显示 —— 必须同时设置 caret 属性并指定 isAnimating={true}
  4. 流式传输期间复制按钮失效 —— 当 isAnimating={true} 时会自动禁用复制按钮
  5. 弹出了链接安全确认框 —— 默认开启;如需关闭可设置 linkSafety={{ enabled: false }}
  6. Next.js 中出现 Shiki 警告 —— 显式安装 shiki 并将其加入到 transpilePackages
  7. allowedTags 不生效 —— 该配置仅对默认的 rehype 插件生效
  8. 数学公式需要用 $$ 而不是 $ —— 默认禁用了单美元符号 $ 以避免与货币符号冲突