首页
/ Storybook `docs.defaultName` 配置详解:为自动生成的文档页自定义侧边栏名称

Storybook `docs.defaultName` 配置详解:为自动生成的文档页自定义侧边栏名称

2026-09-07 21:33:55作者:韦蓉瑛

本文围绕 Storybook 主配置(.storybook/main.js|ts|cjs)中的 docs.defaultName 选项展开,说明它如何决定自动生成的文档页(Autodocs 与 MDX 文档条目)在侧边栏中显示的名称。你将看到完整的 JS / TS / CSF Next(defineMain)配置示例、默认值行为、底层索引生成链路与自动命名规则,以及命名冲突时的报错含义与规避方法。

这一配置项解决什么问题

Storybook 会根据你的故事文件自动生成文档页面。当某个 CSF 文件中的故事带有 autodocs 标签(或在 preview 中全局开启)时,Storybook 会为该组件生成一个文档页,并把它放在组件树的根部;这个页面在侧边栏中的默认名称是 Docsdocs.defaultName 就是用来覆盖这个默认名称的入口:

// 类型形态(摘自 docs/api/main-config/main-config-docs.mdx)
{
  defaultName?: string;
  docsMode?: boolean;
}

它属于 docs 配置(即“配置自动生成文档”的命名空间),同级的 docsMode 用来只显示文档页。而“自动生成文档”功能本身的启用与机制,参见 Autodocs 章节defaultName 在该文档的功能对照表中被描述为:重命名自动生成的文档页面,默认值为 docs: { defaultName: 'Docs' }

如何在 main 配置中设置

.storybook/main.js.storybook/main.ts 中,为顶层 docs 字段传入 defaultName 即可。下面是与官方代码片段一致的完整写法。

CSF 3 + JavaScript(renderer 通用)

export default {
  // Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  docs: {
    defaultName: 'Documentation',
  },
};

CSF 3 + TypeScript(renderer 通用)

// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { StorybookConfig } from '@storybook/your-framework';

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  docs: {
    defaultName: 'Documentation',
  },
};

export default config;

CSF Next(🧪 实验性 API)+ TypeScript:

// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite)
import { defineMain } from '@storybook/your-framework/node';

export default defineMain({
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  docs: {
    defaultName: 'Documentation',
  },
});

采用 CSF Next 写法时,defineMain 的导入来源随框架而不同,其余配置结构完全一致:

renderer defineMain 导入
React(react-vite / nextjs / nextjs-vite) import { defineMain } from '@storybook/your-framework/node'
Vue 3 import { defineMain } from '@storybook/vue3-vite/node'
Angular import { defineMain } from '@storybook/angular/node'
Web Components import { defineMain } from '@storybook/web-components-vite/node'

例如 Vue 3 项目对应为:

import { defineMain } from '@storybook/vue3-vite/node';

export default defineMain({
  framework: '@storybook/vue3-vite',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  docs: {
    defaultName: 'Documentation',
  },
});

Angular、Web Components 仅需替换 import 与 framework 值即可。设置后,重新启动 Storybook,所有自动生成的文档页在侧边栏中都会以 Documentation 命名。

类型定义与默认值出处

docs.defaultName 的语义在类型层已被明确注释,见 core-common.ts

export type DocsOptions = {
  /** What should we call the generated docs entries? */
  defaultName?: string;
  /** Only show doc entries in the side bar (usually set with the `--docs` CLI flag) */
  docsMode?: boolean;
};

其中 “generated docs entries” 即索引(story index)中那些 type: 'docs' 的条目——既包含由 CSF + autodocs 标签自动生成的组件文档页,也包含 MDX 文档条目。当未配置时,代码中通过空值合并运算符回退到字符串 'Docs'(即 API 文档标注的 Default: 'Docs')。

底层实现:名称如何进入文档索引

文档页名称的最终落地发生在核心服务端的索引生成器 StoryIndexGenerator.ts 中。它主要在三条路径读取该选项:

1. 为带 autodocs 标签的 CSF 生成“附加式”文档条目

StoryIndexGenerator.ts 中,当一个 CSF 文件至少包含一个带 autodocs 标签的故事时,会生成一条 type: 'docs' 的文档条目:

const createDocEntry = hasAutodocsTag && !!this.options.docs;

if (createDocEntry && this.options.build?.test?.disableAutoDocs !== true) {
  const docsName = this.options.docs?.defaultName ?? 'Docs';
  const name = docsName;
  const { metaId } = indexInputs[0];
  const entry = storyEntries[0];
  const id = toId(metaId ?? entry.title, name);
  ...

可见 name 直接取 docs.defaultName(缺省为 'Docs'),并且该名称参与了 id 的生成(toId(title, name))。

2. 为 MDX 文档文件生成条目

extractDocs 中,MDX 条目的名称优先级是:MDX 中显式声明的名称 → 附加式 MDX(<Meta of={} />)的自动命名 → 回退到 defaultName

const defaultName = this.options.docs?.defaultName ?? 'Docs';

const name =
  result.name ||
  (csfEntry ? autoName(importPath, csfEntry.importPath, defaultName) : defaultName);

const id = toId(csfEntry?.extra.metaId || result.id || title, name);

其中 result.name 来自 MDX 内 <Meta name="..."> 的显式指定。

3. 文档页与故事同名时的冲突检测

chooseDuplicateStoryIndexGenerator.ts)中,当存在与默认文档页同名的故事条目时,索引会报错并给出修复建议,错误信息里同样读取 defaultName

const docsName = this.options.docs?.defaultName ?? 'Docs';
if (betterEntry.name === docsName) {
  throw new IndexingError(
    `You have a story for ${betterEntry.title} with the same name as your default docs entry name (${betterEntry.name}), so the docs page is being dropped. Consider changing the story name.`,
    ...
  );
}

这三条路径共同说明了一个事实:defaultName 不只是一段显示文本,它还会影响文档条目的 ID 与命名冲突判定。例如默认配置下,测试快照中的文档条目 ID 形如 componentreference--docstags--docs;一旦你把它改成 Documentation,由 toId(title, name) 派生的文档条目 ID 后缀也会随之变化,指向文档页的链接(permalink)同样会变化。这一点从实现可以推断,升级或改配置时需要注意链接的稳定性。

自动命名规则:什么时候真的会用到 defaultName

并非所有 MDX 文档页都会直接使用 defaultName。对通过 <Meta of={ComponentStories} /> 关联到某个 CSF 的“附加式 MDX”,命名规则集中在 autoName.ts

  1. 若 MDX 文件与 CSF 文件的基础名相同(例如 Button.mdxButton.stories.jsx 都基于 Button),则使用 defaultName
  2. 否则使用 MDX 文件去掉扩展名后的文件名。
export function autoName(mdxImportPath: Path, csfImportPath: Path, defaultName: string) {
  const mdxBasename = basename(mdxImportPath);
  const csfBasename = basename(csfImportPath);

  const [mdxFilename] = mdxBasename.split('.');
  const [csfFilename] = csfBasename.split('.');

  if (mdxFilename === csfFilename) {
    return defaultName;
  }

  return mdxFilename;
}

典型行为:

  • Button.mdx + Button.stories.jsx → 使用 docs.defaultName(如 Documentation);
  • ButtonMeta.mdx + Button.stories.jsx → 使用 ButtonMeta
  • 独立的(非附加)MDX 且未显式命名 → 回退到 docs.defaultName

对自动生成文档页(Autodocs)本身,defaultName 则直接作为名称使用。因此,该项目中最常见、也最立竿见影的用法,就是把 Autodocs 页面从默认的 Docs 统一重命名为团队约定名称(如 DocumentationAPIInfo 等)。

索引测试中的验证

以上行为都有测试用例支撑,见 StoryIndexGenerator.test.ts

  • “Allows you to override default name for docs files”用例(约 第 1738 行)将 defaultName 设为 'Info' 后断言索引快照;
  • “errors when a story has the default docs name”用例(约 第 2153 行)将 defaultName 设为 'Story One',验证与故事同名时索引报错;
  • index-json.test.ts__tests__/index-extraction.test.ts 中也以 docs: { defaultName: 'docs' } 作为常规测试配置。

如果你改动该选项后 Storybook 无法正常生成索引,可以参考这些用例的断言来核对名称与 ID 的预期形态。

docsMode 的关系

defaultNamedocsMode 同属 DocsOptions,且都写在 .storybook/main.js 的同一个 docs 块里,示例见 docs-mode 代码片段

export default {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  docs: {
    docsMode: true,
  },
};

二者分工不同:

选项 类型 默认值 作用
defaultName string 'Docs' 自动生成文档页在侧边栏中的名称
docsMode boolean false 侧边栏只展示文档页(通常由 --docs CLI 标志位开启)

也就是说:defaultName 解决“文档页叫什么”,docsMode 解决“是否只保留文档视图”。日常把它俩放在同一个 docs 配置块即可。

使用建议

  • 先在 .storybook/main.js|ts|cjs 中找到或新建顶层 docs 块,再写入 defaultName,无需改动任何故事文件或 MDX;
  • 若团队希望文档入口不叫 Docs 而叫别的名字,这是全局生效的最小改动;个别页面若想单独命名,可在对应 MDX 中使用 <Meta name="...">,其优先级高于自动命名;
  • 注意避免与 defaultName 同名的故事存在(例如不要新建一个名为 Docs 的故事),否则 Storybook 会以索引错误提示该文档页会被丢弃,需要重命名故事或调整默认名;
  • 修改该配置会同步改变文档条目的名称与 ID,若文档页链接已被外部引用,需评估影响后再改。

更完整的功能背景可继续阅读 Autodocs 文档docs 配置 API,并对照 官方代码片段 验证各 renderer 下的写法差异。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
594
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
916
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
516
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388