Markdoc
由 Stripe 开源、基于 Markdown 的声明式内容创作框架与渲染工具链。
项目概述
Markdoc 在可读的 Markdown 之上加入类型化标签、变量、条件与校验能力,并通过可配置的解析、转换和渲染管线生成 HTML 或 React 内容。
Markdoc 是 Stripe 为其公开产品文档设计并开源的 Markdown 内容框架。它把文档解析为抽象语法树,再依据 Schema 将节点和标签转换为可渲染树,最后输出 HTML、静态 React 代码或动态 React 元素。与允许在内容中直接执行任意 JavaScript 的方案不同,Markdoc 强调声明式、机器可读和可验证的内容模型,适合需要自定义组件、内容规则与多渠道渲染的文档平台。
主要特点
Markdoc 将熟悉的 Markdown 写作体验与可控的 Schema、组件和内容处理管线结合起来。
三阶段内容管线
parse 生成 AST,transform 根据配置生成可渲染树,renderer 再输出 HTML 或 React,便于在每个阶段检查和扩展。
声明式自定义标签
使用 {% tag %} 语法表达 Callout、Tabs 等内容组件,无需允许作者在文档中执行任意应用代码。
类型化 Schema
节点和标签可声明子节点、属性类型、默认值、允许值与校验逻辑,使内容约束成为可审查的配置。
节点定制
可重新定义标题、链接、代码块、表格等 CommonMark 节点的属性、校验方式与最终渲染组件。
变量与条件内容
通过配置注入只读变量,并使用 if、else 和自定义函数为不同用户、版本或产品状态生成内容。
Partials 内容复用
可从独立 Markdown 文件引入共享片段,集中维护提示、前置条件和跨页面说明。
静态分析与校验
完整文档都能表示为数据结构,可检测无效属性、非法嵌套和自定义内容规则,并接入 CI。
多种渲染目标
官方提供 HTML、静态 React 和动态 React 渲染方式,也能围绕可渲染树实现其他输出格式。
适用场景
适合既要让作者专注内容,又要由工程团队严格控制组件、数据和输出结果的内容系统。
复杂产品文档
适合包含 Callout、步骤、参数表、代码示例和交互组件的大型开发者文档。
内容驱动的 React 网站
可把安全受控的 Markdoc 标签映射到设计系统组件,同时保持正文接近普通 Markdown。
多版本或个性化指南
变量、条件和函数可根据 API 版本、套餐或用户上下文选择性呈现内容。
企业内部知识平台
Schema 与校验适合统一术语、组件和文档结构,并在合并前发现不符合规范的内容。
自建静态站点生成流程
可把 Markdoc 作为内容层,配合文件系统、路由、搜索索引与任意部署工具形成专用生成器。
多渠道内容输出
同一 AST 和可渲染树可以转换为网页、索引数据或其他内部格式,减少内容源重复。
优点与注意事项
技术选型不仅要看能力,也要理解它带来的团队成本。
主要优点
Markdoc 擅长的地方
- 保留 Markdown 的可读性,同时支持结构化、可组合的内容组件
- 声明式语法不允许任意代码混入正文,作者权限边界更清晰
- Schema 能约束属性和子节点,并提供面向内容的静态校验
- 解析、转换、渲染相互分离,便于测试和定制专用内容管线
- HTML 与 React 官方渲染方式可覆盖静态输出和交互式文档
- 由真实的大型产品文档场景推动设计,并采用宽松的 MIT 许可证
需要注意
采用前应考虑的问题
Markdoc 不直接提供文件路由、导航、搜索、图片管线或部署,需要与 Next.js 等框架或自建构建流程组合。
自定义标签越多,内容 API 的版本管理、组件兼容性和迁移成本越高,应控制原语数量并建立测试。
这是重要的安全与治理优势,但需要高度自由的 MDX 作者可能觉得表达能力受限。
Markdoc 不是通用模板语言,不支持在内容内修改变量或直接编写任意循环逻辑。
动态 React 渲染可以映射交互组件,但状态、数据请求、客户端边界和可访问性仍由应用负责。
核心库不包含 CMS 或可视化编辑器;预览、媒体管理、协作和发布审批需要额外系统。
快速开始
安装核心库,完成 parse、transform、render 三阶段流程,再通过 Schema 增加一个可验证的自定义标签。
bashnpm install @markdoc/markdoctypescriptimport Markdoc from "@markdoc/markdoc";
const source = `
# Docs100
使用 **Markdoc** 构建可验证的项目文档。
`;
const ast = Markdoc.parse(source);
const content = Markdoc.transform(ast);
const html = Markdoc.renderers.html(content);
console.log(html);typescript// markdoc.config.ts
import type { Config } from "@markdoc/markdoc";
export const config: Config = {
tags: {
callout: {
render: "Callout",
children: ["paragraph", "list", "tag"],
attributes: {
type: {
type: String,
default: "note",
matches: ["note", "warning"],
errorLevel: "critical",
},
title: {
type: String,
required: true,
},
},
},
},
};markdown# 快速开始
{% callout type="note" title="准备工作" %}
请先安装 Node.js,并确认项目使用受支持的模块系统。
{% /callout %}
## 下一步
继续配置节点、变量与内容校验。tsximport Markdoc from "@markdoc/markdoc";
import { config } from "./markdoc.config";
function Callout({
title,
type,
children,
}: React.PropsWithChildren<{
title: string;
type: "note" | "warning";
}>) {
return (
<aside data-type={type}>
<strong>{title}</strong>
{children}
</aside>
);
}
export function Document({ source }: { source: string }) {
const ast = Markdoc.parse(source);
const errors = Markdoc.validate(ast, config);
if (errors.length > 0) {
throw new Error("Markdoc 内容校验失败");
}
const content = Markdoc.transform(ast, config);
return Markdoc.renderers.react(content, React, {
components: { Callout },
});
}typescriptconst source = `
{% if $plan == "pro" %}
你可以使用高级分析功能。
{% else /%}
升级套餐后可使用高级分析功能。
{% /if %}
`;
const ast = Markdoc.parse(source);
const content = Markdoc.transform(ast, {
variables: {
plan: "pro",
},
});
const html = Markdoc.renderers.html(content);下一步:先把节点、标签和变量限制在少量稳定的内容原语中,并在构建或 CI 阶段执行 Markdoc.validate;等编辑需求明确后,再扩展 Partials、函数与框架集成。
类似项目
这些项目也能连接 Markdown、结构化内容和组件系统,但抽象层级与运行方式各不相同。
Docusaurus
由 Meta 维护,使用 React、MDX 和插件系统构建文档及内容网站的静态站点生成器。
查看项目MkDocs
使用 Python、Markdown 和 YAML 配置构建项目文档的静态站点生成器。
查看项目Astro
面向内容网站的 Web 框架,默认发送更少的客户端 JavaScript。
查看项目Eleventy
灵活、稳定且支持多种模板语言的 JavaScript 静态站点生成器。
查看项目Next.js
基于 React 的全栈 Web 框架,覆盖渲染、路由和部署。
查看项目MDX
允许在 Markdown 文档中直接使用 JSX 与组件的可编程内容格式。
访问官网Markdoc vs MDX
Markdoc 与 MDX 都让 Markdown 能够承载组件化内容。Markdoc 使用声明式标签和 Schema,将内容限制为可分析的数据;MDX 则把 Markdown 与 JSX、JavaScript 表达式结合,为作者提供更直接的编程能力。
| 比较维度 | Markdoc | MDX |
|---|---|---|
| 内容语法 | Markdown 加 {% tag %}、变量与内置条件 | Markdown、JSX、ESM 与 JavaScript 表达式 |
| 执行模型 | parse、transform、render 的声明式管线 | 把内容编译为可执行的 JavaScript/JSX 模块 |
| 组件映射 | Schema 的 render 名称映射到受控组件 | 在文档中导入或由 Provider 注入组件 |
| 内容校验 | 内置节点、属性、子节点与自定义校验 | 主要依赖 TypeScript、编译器和额外检查工具 |
| 作者权限 | 不能混入任意代码,内容能力由配置明确开放 | 可使用 JSX 和表达式,灵活性与代码权限更高 |
| 运行时数据 | 由配置注入只读变量与自定义函数 | 可使用组件 Props、导入和 JavaScript 逻辑 |
| 渲染目标 | 官方支持 HTML、静态 React 和动态 React | 主要面向支持 JSX 的 React 生态 |
| 更适合 | 大型受控文档、内容治理和多输出管线 | 开发者主导、需要高度组件自由度的内容站 |
如果内容由不同角色共同维护,需要稳定的组件契约、严格校验和清晰的代码执行边界,Markdoc 更容易治理;如果作者本身就是 React 开发者,希望直接导入组件、编写表达式并接受内容即代码的模型,MDX 通常更顺手。无论选择哪种方案,都应先用真实的复杂页面验证编辑、预览、升级和安全流程。
资料核验
版本、维护信息与本页采用的官方资料来源。
本次核验覆盖 Markdoc 的官方定位、MIT 许可证、安装方式、解析—转换—渲染流程,以及节点、标签、变量和 React 渲染能力。Markdoc 是内容框架而非完整站点生成器,采用前还应核对宿主框架集成、最新版本与安全公告。
官方仓库未归档,核验时最近可见的代码活动日期为 2025 年 8 月 5 日。项目更新频率较低但仍有维护迹象,因此标记为稳定维护,而不是活跃更新。