Storybook:基于故事标签为预览iframe头部添加不同脚本标签
给特定Storybook故事的预览iframe头部添加HTML标签的方案
你可以通过故事参数+全局装饰器的组合实现这个需求,不需要依赖全局previewHead,具体方案如下:
1. 核心思路
给需要自定义头部的故事标记特定参数,然后在全局装饰器中检测该参数,动态向预览iframe的head注入/移除HTML标签,确保只对目标故事生效,不污染全局环境。
2. 具体实现步骤
步骤1:在preview.js中添加全局装饰器
这个装饰器会监听每个故事的参数,按需注入标签,并在故事切换时清理:
export const decorators = [ (Story, context) => { // 读取故事配置的自定义参数 const { injectHeadTags } = context.parameters; if (!injectHeadTags) return <Story />; // 示例:创建并注入样式标签 const styleTag = document.createElement('style'); styleTag.id = 'custom-story-style'; styleTag.textContent = injectHeadTags.styleContent || ''; // 示例:创建并注入脚本标签(如果需要) let scriptTag = null; if (injectHeadTags.scriptSrc) { scriptTag = document.createElement('script'); scriptTag.id = 'custom-story-script'; scriptTag.src = injectHeadTags.scriptSrc; } // 注入到head if (styleTag) document.head.appendChild(styleTag); if (scriptTag) document.head.appendChild(scriptTag); // 故事卸载时移除标签,避免影响其他故事 return () => { if (styleTag && document.getElementById('custom-story-style')) { document.head.removeChild(styleTag); } if (scriptTag && document.getElementById('custom-story-script')) { document.head.removeChild(scriptTag); } return <Story />; }; }, ];
步骤2:给目标故事添加参数配置
在需要自定义头部的故事中,添加parameters.injectHeadTags参数,传入你要注入的内容:
import { MyComponent } from './MyComponent'; export const WithCustomHead = { parameters: { injectHeadTags: { styleContent: ` body { background-color: #f5f5f5; } .custom-component { border-radius: 8px; } `, // 如果需要脚本,添加scriptSrc: '/path/to/your/script.js' }, }, render: () => <MyComponent />, };
3. 其他可选方案
局部装饰器(针对单个组件的所有故事)
如果某个组件的所有故事都需要相同的头部标签,可以直接在组件的stories文件中添加局部装饰器,不用全局配置:
export default { title: 'Components/MyComponent', component: MyComponent, decorators: [ (Story) => { const linkTag = document.createElement('link'); linkTag.rel = 'stylesheet'; linkTag.href = '/path/to/custom.css'; document.head.appendChild(linkTag); return () => { document.head.removeChild(linkTag); return <Story />; }; }, ], };
注意事项
- 给注入的标签添加唯一
id,避免重复注入或无法清理 - 脚本标签如果需要执行逻辑,可通过
onload事件确保加载完成后再运行 - 如果需要更复杂的逻辑(比如基于标签动态加载资源),可以扩展这个装饰器的参数逻辑
内容的提问来源于stack exchange,提问作者Philipp Kyeck
相关产品推荐
相关产品推荐

