Storybook 的 `previewHead` 与 `previewBody` 配置指南:以编程方式调整预览 HTML

发布时间:2026/10/25 13:20:16

Storybook 的 `previewHead` 与 `previewBody` 配置指南:以编程方式调整预览 HTML Storybook 的previewHead与previewBody配置指南以编程方式调整预览 HTML【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook本篇指南讲解 Storybook 中两个由 Preset 驱动的配置入口previewHead与previewBody。它们在.storybook/main.js或main.ts中通过函数接收 Storybook 渲染 iframe 当前的head、body内容并返回修改后的字符串可用于按环境条件注入脚本、样式或字体也能被 addon 作者用于封装 UI 定制能力。读完本文你将掌握两种配置的签名、适用场景、静态文件preview-head.html/preview-body.html与编程方案的取舍以及底层模板是如何与 HTML 文件合并的。配置项速览类型与文档位置previewHead与previewBody属于 main.js|ts 顶层配置 家族官方文档分别定义在main-config-preview-head.mdx类型为(head: string) string用于程序化调整预览区head。main-config-preview-body.mdx类型为(body: string) string用于程序化调整预览区body。在类型层面它们被统一声明在核心类型模块 code/core/src/types/modules/core-common.ts 中/** * Programmatically modify the preview head/body HTML. The previewHead and previewBody functions * accept a string, which is the existing head/body, and return a modified string. */ previewHead?: PresetValueStorybookConfigRaw[previewHead]; previewBody?: PresetValueStorybookConfigRaw[previewBody];注意这里的PresetValue语义这两个字段本质上是 Preset 入口preset 机制的一个组成部分。也就是说它们并不只是你项目的某次性配置而是 Storybook 在加载、合并 presets 时对每个 preset 的previewHead/previewBody依次调用后拼接得到最终 HTML 的预设值。正因如此writing-presets.mdx 明确指出预设 API 提供对 UI 配置的访问包括通过previewHead与previewBody配置的 preview 的head、bodyHTML 元素与使用preview-head.html、preview-body.html文件的效果类似。调用链路common-preset.ts在实现层面Storybook 的核心预设 code/core/src/core-server/presets/common-preset.ts 提供了两个核心 preset 函数export const previewHead async (base: any, { configDir, presets }: Options) { const interpolations await presets.applyRecordstring, string(env); return getPreviewHeadTemplate(configDir, interpolations); }; export const previewBody async (base: any, { configDir, presets }: Options) { const interpolations await presets.applyRecordstring, string(env); return getPreviewBodyTemplate(configDir, interpolations); };它们做的事是先通过presets.apply(env)收集环境变量插值再读取模板文件内容详见下文模板如何生成拿到已有字符串后交给你的previewHead(head ...)/previewBody(body ...)修改。换句话说你函数收到的字符串参数是底层模板已经渲染好的head/body内容你只需在其基础上追加或改写并原样返回。何时用编程式配置、何时用静态 HTML 文件Storybook 提供了两套等价机制向预览 iframe 注入内容需求场景静态 HTML 文件方案编程式 preset 方案注入固定脚本 / 样式无需条件判断在.storybook/preview-head.html或preview-body.html中添加内容无需使用previewHead/previewBody按环境、按特性开关条件注入无法实现HTML 文件是纯静态的previewHead/previewBody函数返回拼接结果开发插件 / addon 需要修改 UI用户难以复用 addon 的逻辑addon 在 preset 中导出这两个字段随 addon 一并生效官方文档在 main-config-preview-head.mdx 给出的 Callout 很明确如果你不需要程序化调整 preview 的head可以直接改用preview-head.html添加脚本与样式previewBody对应preview-body.html。反之需要条件判断或要在 addon 里封装能力时就使用previewHead/previewBody函数。这个设计在 template.ts 的实现中也得到印证模板函数会先检查.storybook/preview-head.html/preview-body.html是否存在存在则把静态文件内容与内置基础模板拼接再交给预设管线。也就是说HTML 文件方案与函数方案并不会冲突而是分层处理——文件内容先被合并进基础 HTML你的函数再拿到合并结果做最后一步加工。模板如何生成preview-head.html/preview-body.html与基础模板合并previewHead/previewBody的函数参数到底长什么样看 code/core/src/common/utils/template.ts 的实现export function getPreviewHeadTemplate(configDirPath, interpolations?) { const base readFileSync( join(resolvePackageDir(storybook), assets/server/base-preview-head.html), utf8 ); const headHtmlPath resolve(configDirPath, preview-head.html); let result base; if (existsSync(headHtmlPath)) { result readFileSync(headHtmlPath, utf8); } return interpolate(result, interpolations); }对应地getPreviewBodyTemplate的逻辑是将用户preview-body.html的内容前置到内置基础模板base-preview-body.html之前再合并。两处都会经过interpolate()做环境变量插值——即把%VAR_NAME%占位符替换为presets.apply(env)得到的环境变量值。配套单元测试 code/core/src/common/utils/tests/template.test.ts 也验证了两个关键行为当.storybook/preview-body.html不存在时返回空内容 / 仅基础模板当文件存在时返回用户文件内容 基础模板的合并结果。值得注意的实现细节head合并时静态内容被追加到基础模板之后result fileContent而body合并时静态内容被插入到基础模板之前fileContent result。这意味着你自定义的head内容会出现在 Storybook 内置 head 内容之后通常更适合做覆盖而自定义 body 内容会出现在基础 body 之前。在.storybook/main.ts中使用previewHead文档示例的主用法是按环境条件注入样式或脚本。以 CSF 3 与标准配置文件为例修改 代码示例片段 中Head (CSF 3)对应的 TS 写法previewHead版本其他渲染器与格式仅导入路径不同// .storybook/main.ts // 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 { previewHead: (head) ${head} style html, body { background: #827979; } /style , }; export default config;核心要点必须保留${head}收到的参数是当前已有head内容的完整字符串忘记拼接会直接破坏 Storybook 预览所需的既有脚本与样式。返回完整的新字符串你的函数签名是(head: string) string返回什么Storybook 就使用什么。JSCommonJS/ESM写法与之完全一致只是把类型注解去掉、直接导出对象// .storybook/main.js export default { previewHead: (head) ${head} style html, body { background: #827979; } /style , };在.storybook/main.ts中使用previewBodypreviewBody的签名是(body: string) string典型用法是在页面底部按条件追加第三方脚本例如分析脚本。文档中的 Body 示例CSF 3 的 TS 写法为// .storybook/main.ts // 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 { previewBody: (body) ${body} ${ process.env.ANALYTICS_ID ? script srchttps://cdn.example.com/analytics.js/script : } , }; export default config;这里展示了与previewHead不同的典型用途把注入逻辑建立在环境变量判断之上process.env.ANALYTICS_ID存在时才输出script标签因为返回的是普通字符串你可以做任意字符串处理如条件拼接、压缩空白或插值使用该功能时开发与生产构建环境下process.env的可用变量以 main-config-env 描述的加载机制为准。各框架 / 格式的代码形态CSF 3 与 CSF Next针对不同渲染器和新的配置写法官方代码片段 main-config-preview.md 覆盖了多个变体完整包含写法形态导入来源配置对象CSF 3.storybook/main.js直接导出{ previewHead, previewBody }普通对象字面量CSF 3.storybook/main.tsimport type { StorybookConfig } from storybook/your-framework类型为StorybookConfigCSF Next 实验性main.tsimport { defineMain } from storybook/your-framework/node用defineMain({ ... })包裹CSF Next 的实验形态示例以 Vue 渲染器为例// .storybook/main.ts import { defineMain } from storybook/vue3-vite/node; export default defineMain({ previewHead: (head) ${head} style html, body { background: #827979; } /style , });而 React 系列的 CSF Next 写法把类型导入从主包换到 Node 入口如storybook/react-vite/nodeAngular 为storybook/angular/nodeWeb Components 为storybook/web-components-vite/node。JS 文件同样支持defineMain只需去掉类型注解。需要区分文档中的previewHead/previewBody配置与另一组head/body静态文件方案并不冲突同时配置时按前面模板如何生成一节的顺序合并。此外向**管理界面manager**注入内容应使用 main-config-manager-head 对应的机制不要与这里的预览区配置混用。典型场景与最佳实践小结综合官方文档与源码可以总结以下使用建议addon 作者的首选封装官方在 main-config-preview-head.mdx 与 main-config-preview-body.mdx 中明确写Most often used by addon authors最常被插件作者使用。addon 在自身 preset 中导出previewHead/previewBody用户安装后即可自动获得注入效果无需手动编辑 HTML 文件。条件注入优先用函数从仓库的common-preset.ts看函数形式在整个 preset 管线中最后执行拿到的是合并后的完整内容因此可以基于process.env或自身逻辑决定保留、替换或追加。永远保留入参前缀两个函数都是接收完整字符串 → 返回完整字符串的纯函数式约定见 core-common.ts 的注释漏掉${head}/${body}会导致 Storybook 预览页面缺失运行时所需的基础 HTML。静态内容优先用文件若注入的是固定不变的脚本/样式直接用preview-head.html/preview-body.html更直观、无需经过函数层仓库模板函数template.ts会自动检测并合并这些文件。头部与 body 的合并顺序不同自定义 head 内容追加在基础 head 之后、自定义 body 内容前置在基础 body 之前涉及样式覆盖或首个脚本执行时机时可利用这一顺序差异。通过previewHead与previewBody你可以在不修改 Storybook 内部渲染模板的前提下对组件预览 iframe 的文档头部与正文做精确、可复用、可条件化的定制——无论是为项目引入全局主题样式、按环境加载分析脚本还是以 addon 形式向用户交付开箱即用的 UI 增强能力。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/25 12:27:14

基于multisim的产品数字计件器电路设计

任务要求: 产品数字计件器是用于准确地完成工厂产品出厂传送带中的产品计件和统计显示。按下启动按钮,设备会自动扫描对产品数量进行计数、显示和存储,并显示计数结果。需要重置计数器时,按下清零按钮即可。 技术要求:…

2026/10/25 13:19:30

AI应用架构设计:可落地、可验证、可演进的图解实践

1. 这不是PPT,是能跑起来的AI应用架构图谱“图解AI应用架构设计”——这六个字最近在技术社区里反复刷屏,但很多人点开后发现,要么是几张泛泛而谈的分层框图,写着“数据层→模型层→服务层”,配个云朵图标;…

2026/10/25 13:19:30

线性回归:深度学习的基石与工业级实现

1. 为什么线性回归是深度学习的必修第一课刚接触深度学习的新手常被各种复杂网络结构吓到,但所有花哨的模型本质上都在做同一件事——找到输入与输出之间的数学映射关系。而线性回归正是这种思想最纯粹的体现:用直线ywxb拟合数据点。我在带团队新人时发现…

2026/10/25 13:19:30

YOLO26目标检测模型改进与SCFM模块技术解析

1. YOLO26改进方案概述最近在目标检测领域,YOLO系列模型又迎来了重要更新。YOLO26作为该系列的最新成员,在保持实时检测优势的同时,通过引入空间-通道特征调制器(SCFM)模块,显著提升了模型的特征表达能力。…

2026/10/25 13:19:30

Seedream4.5图像生成API调用与Python实战

1. Seedream4.5图像生成模型API调用实战指南最近在做一个创意设计项目时,发现Seedream4.5的AI图像生成效果相当惊艳。作为Python开发者,自然想通过代码调用它的API来实现自动化图像生成。经过两周的摸索和调试,终于跑通了整个流程&#xff0c…

2026/10/25 13:19:30

KITTI多模态时空对齐可视化:激光雷达点云与相机图像精准投影

简介:本资源是一个面向自动驾驶与三维感知研究者的KITTI数据集可视化工具集,专为点云处理初学者及算法工程师设计,解决原始.bin点云文件难以直观理解、BEV视图构建困难、多模态标注协同分析不便等实际问题。压缩包共42个文件,包含…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑