跳到主要内容

文档写作规范

本地开发​

npm install # 首次
npm start # 本地预览,默认 http://localhost:3000
npm run build # 生产构建,会检查死链
npm run serve # 预览构建产物
npm run typecheck

npm run build 会因为死链直接失败(onBrokenLinks: 'throw'),这是刻意的——文档里的链接必须一直有效。

新增一篇文档​

  1. 在 docs/ 下建 .md 文件,路径即 URL:docs/products/foo.md → /docs/products/foo。

  2. 写 front matter:

    ---
    id: foo
    title: Foo
    sidebar_position: 9
    description: 一句话说明,会用作 SEO 描述
    ---
  3. 把文档 id 加进 sidebars.ts 的对应分组(本站侧边栏是手工维护的,不加就不会出现在导航里)。

写作约定​

  • 文档间链接用相对路径加扩展名:[FlowMax](../products/flowmax.md)。这样构建时能校验,重命名文件也能被发现。
  • 链接 static/ 里的静态文件要用 pathname:// 前缀:[Pitch](pathname:///prototypes/traderx-pitch.html),否则 Docusaurus 会当成路由去解析并报死链。
  • 未定的内容写成 待补充 清单,用 - [ ] 列出具体待决策项,而不是留白。空文档比没有文档更误导人。
  • 状态词统一口径:规划中 / 方案设计中 / 开发中 / 已上线。改了产品页的状态,同步改产品矩阵的表格。
  • 日期写绝对日期(2026-03-22),不要写「上周」「下个月」。

提示框​

:::note[说明]
正文
:::

可用类型:note / tip / info / caution / warning / danger。

标题必须写在方括号里。Docusaurus v3 用的是 directive 语法,旧的 :::note 说明 空格写法解析不出来,整块会退化成一行纯文本——而且构建不报错,只能靠肉眼发现。

Mermaid 图​

已启用 Mermaid,直接用代码块:

```mermaid
flowchart LR
A --> B
```

草稿与内部内容​

  • 加 draft: true 让文档只在本地开发时可见,生产构建会跳过。
  • 加 unlisted: true 让文档可访问但不进侧边栏、不进搜索、不进 sitemap。

发布动态​

blog/ 目录挂在 /updates 路由下,用于产品进展和内部通告。新增一篇:

blog/2026-09-10-标题.md

front matter 里的 authors 取自 blog/authors.yml,tags 取自 blog/tags.yml——新作者/新标签要先在这两个文件里登记。

发布深度文章​

insights/ 目录挂在 /insights 路由下(导航栏的「深度文章」),用于技术、产品、行业与理念的长文。它和 blog/ 是两个互相独立的实例:各自的列表页、标签页、RSS,以及各自的 authors.yml 和 tags.yml——insights/ 里的文章只能引用 insights/tags.yml 里登记的标签。

新增一篇,文件名必须以日期开头(日期决定发布时间和排序):

insights/2026-09-10-industry-landscape.md

front matter 模板:

---
slug: industry-landscape # URL:/insights/industry-landscape,用英文,和文件名解耦
title: 行业现状:三合一赛道的收敛方向 # 页面标题,不要再在正文里写 # 一级标题,会重复
authors: [OrderK] # 取自 insights/authors.yml 的 key,可多个
tags: [industry, thesis] # 取自 insights/tags.yml 的 key
description: 一句话摘要,用于 SEO 和社交卡片
---

正文写完开头一两段后插入截断标记,它上面的内容会作为列表页的摘要:

{/* truncate */}

三个最常踩的坑:

  • 作者 key 没登记:authors: [OrderK] 里的 OrderK 必须先出现在 insights/authors.yml,否则构建直接报 Blog author with key "X" not found。标签同理。
  • 正文里又写了一级标题:title 已经会渲染成 H1,正文再写 # xxx 就会出现两个标题。正文从 ## 开始。
  • 从别处粘贴的表格:Notion / 飞书 / 网页复制过来的表格是制表符分隔的纯文本,Markdown 不认,会渲染成一大段连排文字。必须改成 | 列 | 列 | 加分隔行 | --- | --- | 的标准写法。

两个栏目的分工:

动态公告 blog/深度文章 insights/
写什么发布记录、进展、内部通告一篇讲清一个判断
时效强,过期就归档弱,写完要能放两年
长度几百字不限,该多长就多长

深度文章的写法约定:写明依据,并写明可能错在哪里。只有结论没有依据的文章,半年后没人能判断它是否还成立。技术实现细节写进 docs/,insights/ 回答的是「为什么这么选」。

两个栏目都需要 {/* truncate */},标记列表页的摘要截断位置——不写会在构建时警告。

图片与静态资源​

分两类放,用途不同,不要混:

产品 Logo 与站点级资源 → static/img/​

static/img/
favicon.ico
logo.svg # navbar 主 logo
social-card.jpg # 分享卡片默认图(og:image),1200x630
logos/
traderx.svg
flowmax.svg
polyedge.svg
seashell.svg

分享到微信/X/Telegram 时显示的大图来自 themeConfig.image,全站共用 img/social-card.jpg。单篇文章想换图,在 front matter 里写 image: /img/xxx.png 即可覆盖(注意开头的 /)。描述文字则来自各页自己的 description,两者是分开的——只改 description 不会换图。

会被多个页面复用、或者被 docusaurus.config.ts 引用的资源放这里——config 里的 favicon、navbar.logo.src、themeConfig.image 只认 static/ 下的 URL 路径,写相对路径无效。

引用方式:

  • Markdown:![FlowMax](/img/logos/flowmax.svg),开头的 / 就是 static/
  • TSX 组件:import FlowMax from '@site/static/img/logos/flowmax.svg'; 再 <FlowMax />,SVG 会被 SVGR 转成 React 组件,可以用 CSS 控制颜色和尺寸

Logo 优先用 SVG;只有 PNG 时保证宽度 ≥ 512px。

文章配图 → 跟 Markdown 放一起​

配图放在文档同级的 img/ 目录,用相对路径引用:

docs/products/
flowmax.md
img/
flowmax-order-flow.png -> ![订单流](./img/flowmax-order-flow.png)

docs/products/polyedge/
index.md
img/
fee-flow.png -> ![手续费流转](./img/fee-flow.png)

为什么不统一丢 static/:相对路径的图会经过 webpack 处理,图片不存在时构建直接失败,和死链检查是一个思路;文件名还会带 hash,利于长期缓存。放 static/ 的图路径写错只会在线上变成裂图,构建时不报错。

博客多图时把文章改成目录形式:

blog/2026-09-10-docs-site-online/
index.md
img/screenshot.png

命名用小写连字符,带上下文:flowmax-order-flow.png,不要 image1.png、截图.png。

视频 → 不要进仓库​

Cloudflare Pages 的硬限制是单文件 25 MiB、单次部署 20,000 个文件,视频进 static/ 很容易撞上限,也会撑爆 Git 仓库。

  • 正片(> 5 MB):传 Cloudflare Stream,文档里嵌播放器(需要 JSX 属性写法时文件后缀改成 .mdx):

    <iframe
    src="https://customer-xxx.cloudflarestream.com/<video-id>/iframe"
    style="border: none; width: 100%; aspect-ratio: 16/9"
    allowfullscreen></iframe>
  • 不需要转码的:传 R2,绑 cdn.traderx.fun 直链,用 <video controls src="..."></video>

  • 短演示(< 5 MB):可以做成 WebM 放 static/video/,但优先还是走 Stream