For AI agents: the complete documentation index is available at /zh/llms.txt, the full documentation bundle is available at /zh/llms-full.txt, and this page is available as Markdown at /zh/guide/customization.md.
  • 中文
  • 样式与组件定制

    库输出稳定的 wtr-* 类名与一组 CSS 变量。页面结构、文案、标题锚点和组件外观都可以在不改源码的情况下调整。

    样式

    引入一次页面样式:

    import "react-wikitext/styles.css";
    • 库不设置全局元素样式,页面字体默认继承自宿主。
    • 根容器是 div.wtr-view;自有类名以 wtr- 前缀开头,同时保留一部分 MediaWiki 兼容类名。
    • 内联样式只保留白名单内的排版与外观声明,危险值整条丢弃;严格 CSP 下可按需放行 style-src。

    CSS 变量

    变量用途
    --wtr-text正文颜色
    --wtr-muted次要文本
    --wtr-border边框与分隔线
    --wtr-accent链接与强调色
    --wtr-accent-soft强调背景
    --wtr-placeholder-bg占位背景
    --wtr-danger错误与阻止提示
    --wtr-font-mono等宽文本

    变量定义在 :root,可以在任意祖先覆盖:

    .article-theme {
      --wtr-text: #1f2328;
      --wtr-accent: #0969da;
      --wtr-border: #d0d7de;
    }

    深色主题可以通过 [data-wtr-theme="dark"] 或宿主自己的选择器覆盖同一组变量。

    容器属性

    <Wikitext
      source={source}
      lang="zh-CN"
      dir="ltr"
      className="article"
      containerProps={{ "data-page": "example" }}
    />

    className 与 containerProps.className 会和 wtr-view 合并。containerProps 在类型层排除了 dangerouslySetInnerHTML。

    文案

    所有用户可见的占位与提示都来自 labels。准备选项接受 Partial<WikitextLabels>,未提供的字段沿用默认英文文案。

    <Wikitext
      source={source}
      prepareOptions={{
        labels: {
          templateNotExpanded: "模板未展开",
          parserFunctionNotEvaluated: "解析器函数未求值",
          filePlaceholder: "文件",
          reference: "引用",
          toc: "目录",
          categories: "分类",
          unknownNode: "不支持的结构",
          redirectTo: "重定向至",
          blockedLink: "链接已拦截",
          blockedHtml: "HTML 已拦截",
          renderFailed: "渲染失败",
          nestedTableUnsupported: "不支持嵌套表格",
        },
      }}
    />
    字段默认值
    templateNotExpandedTemplate not expanded
    parserFunctionNotEvaluatedParser function not evaluated
    filePlaceholderFile
    referenceReference
    tocContents
    categoriesCategories
    unknownNodeUnsupported node
    redirectToRedirect to
    blockedLinkBlocked link
    blockedHtmlBlocked HTML
    renderFailedRender failed
    nestedTableUnsupportedNested table not supported

    实际生效的文案会写入 WikitextRenderDocument.meta.labels,视图与组件读取同一份文案。

    标题锚点

    type WikitextHeadingIdStrategy = "instance" | "mediawiki" | "none";
    策略行为
    instance(默认)准备阶段生成逻辑锚点;视图按实例前缀映射 DOM id,多实例不冲突
    mediawiki写入裸锚点,视图不追加前缀;适合与宿主约定一致的单实例页面
    none不写 id,也不生成目录链接
    • 锚点由移除标记后的标题文本生成:空白转为 _,重复 id 按大小写不敏感追加 _2、_3,空标题使用 section-{n}。
    • 语义标题与源码 h1–h6 都参与锚点生成。
    • idPrefix 只在 instance 下生效;未传时使用 React useId 生成的实例前缀。
    • 视图同时映射标题 id、文档内 #fragment 链接和表格 headers 属性。

    标题列表直接读取渲染快照:

    for (const heading of prepared.headings) {
      console.log(heading.level, heading.text, heading.id);
    }

    组件覆盖

    覆盖点按优先级从高到低排列:

    1. semanticComponents[type]:替换整个 wiki 语义结构。
    2. components[tag]:替换默认 HAST 结构内部的 HTML 标签。
    3. 原生元素。

    HTML 组件

    <WikitextView
      document={prepared}
      components={{
        blockquote: ({ children, className }) => (
          <blockquote className={[className, "doc-quote"].filter(Boolean).join(" ")}>
            {children}
          </blockquote>
        ),
      }}
    />

    components 按 HAST 标签名映射,键可以是 p、table、img、a 等。组件会收到经过安全校验的属性、node(HAST 元素)、document、可选的 semantic 节点与 origin。不要把非 DOM 属性直接展开到原生元素上。

    语义组件

    import { WikitextFragment, type WikitextTemplateComponentProps } from "react-wikitext/view";
    
    function TemplateCard({ displayName, node }: WikitextTemplateComponentProps) {
      return (
        <aside className="template-card">
          <strong>{displayName}</strong>
          <WikitextFragment nodes={node.children} mode="block" />
        </aside>
      );
    }
    
    <WikitextView document={prepared} semanticComponents={{ template: TemplateCard }} />;

    可覆盖的语义类型:

    类型属性中的额外字段
    linktarget、kind、href?、external
    template / parserFunctiondisplayName
    argument—
    filename
    referencenumber
    extensionname、block
    unknownparsedType、block
    table—
    • semanticComponents.extension 会收到除 ref 外的扩展节点;ref 使用 reference,<references> 不产生组件调用。
    • semanticComponents.reference 只替换 <sup>,文末引用区仍由库生成。
    • WikitextFragment 必须在 WikitextView 的 Context 内使用,nodes 必须是当前渲染文档中的同一批节点对象。它适合渲染默认转换函数不会输出的子内容,例如模板参数、文件说明和 ref 内容。
    Warning

    components 与 semanticComponents 属于可信代码;组件输出的 HTML 不再经过库清洗。解析函数返回的 URL 已在准备阶段校验,但组件仍应避免把未经验证的输入插入危险属性。

    读取上下文

    import { useWikitextIds, useWikitextLabels } from "react-wikitext/view";
    
    function SectionLink() {
      const labels = useWikitextLabels();
      const ids = useWikitextIds();
      return <a href={ids.toHref("#section-1")}>{labels.toc}</a>;
    }
    • useWikitextContext() 提供 document、索引、组件表、idPrefix、mapId、mapHref 与 onRenderError。
    • useWikitextLabels() 读取当前渲染快照的文案。
    • useWikitextIds() 提供 toDomId 与 toHref。

    这些 Hook 与 WikitextFragment 必须在 <WikitextView> 内使用。

    插件

    <Wikitext
      source={source}
      prepareOptions={{
        wikitextPlugins: [
          () => (tree, file) => {
            // 在克隆的语义 AST 上运行
            return tree;
          },
        ],
        rehypePlugins: [
          () => (tree) => {
            for (const child of tree.children) {
              if (child.type === "element" && child.tagName === "p") {
                const classes = child.properties.className;
                child.properties.className = [
                  "doc-paragraph",
                  ...(Array.isArray(classes) ? classes : []),
                ];
              }
            }
            return tree;
          },
        ],
      }}
    />
    • wikitextPlugins 在克隆的语义树上运行;rehypePlugins 在 HAST 转换后、最终清洗前运行。
    • 插件签名沿用 unified 的 (tree, file),其中 file 是 VFile。
    • 原始解析快照不会被修改;准备后会对工作树重新分配 id。
    • 同步入口不接受异步插件,异步插件需要 prepareWikitextAsync。
    • 最终安全清洗始终在 rehype 插件之后执行,插件不能绕过白名单与图片授权。

    插件列表是结构化数组,元素可以是插件函数或 [plugin, options] 元组,按顺序执行。

    安全策略

    prepareOptions.policy 可以调整 URL 与标签白名单。默认值:

    {
      allowRelativeLinks: true,
      allowRelativeImages: false,
      allowPluginImages: false,
      externalLinkTarget: "_blank",
      extraTags: [],
      stripTags: [
        "script", "style", "iframe", "object", "embed", "form", "input",
        "button", "textarea", "select", "option", "svg", "math", "meta", "link",
      ],
    }

    policy 与默认值单层浅合并;数组字段整体替换。class 只按 [A-Za-z0-9_-] 安全字符集过滤,不提供放宽或收窄选项。需要白名单之外的标签、属性或富展示时,优先通过 /view 的组件覆盖实现,不要放宽清洗规则。

    自定义语义节点

    自定义节点需要同时扩展 WikitextNodeMap 并在 prepareOptions.handlers 注册对应的 HAST 转换函数。未注册转换函数的节点会产生诊断并降级为源码卡片。转换函数的上下文、预算与转换细节见准备 API。