Import assets into stories
You can import media assets by importing or requiring them directly into story files. This works out of the box with the default Storybook configuration. If using a custom webpack config, you must add the file loader to handle the required files.
Relative paths for subpath deployments
When deploying Storybook into a subpath (like https://example.com/storybook), all images and media files must use relative paths so the browser can locate them. If you load static content via importing, relative paths are automatic. If serving assets from a static directory, use relative paths to load images or use the base element.
Referencing fonts in stories
After configuring Storybook to serve assets from your static folder, you can reference those assets in Storybook. To reference and apply a custom font to your stories, create a preview-head.html file inside the configuration directory (.storybook) and add a <link /> tag to reference your font.
Static assets with Vite-based frameworks
When using Vite-based frameworks, additional directories may be copied to your build directory because of Vite's own static asset handling. You can set Vite's publicDir option to false to disable this behavior.
CDN for asset hosting
You can upload files to an online CDN and reference them in your stories instead of serving them locally.
staticDirs configuration for serving static files
Configure a directory or list of directories where assets live by using the staticDirs configuration element in the main Storybook configuration file (.storybook/main.js|ts). This ensures components always have the assets they need to load. You can specify a single directory, a list of directories separated by commas without spaces, or use a configuration object to define the directories.
Setting base font-size with preview-body.html
If using relative sizing in your project (like rem or em), you may update the base font-size by adding a style tag to preview-body.html.
Adding elements to preview iframe head
To add extra elements to the head of the preview iframe (such as stylesheets, font files), create a file called `.storybook/preview-head.html` and add tags there. These tags will be injected into the preview iframe where components render, not the Storybook application UI.
Adding elements to preview iframe body
To add different tags to the body of the preview iframe (helpful for custom content roots), create a file called `.storybook/preview-body.html` inside the `.storybook` directory. These tags will be injected into the preview iframe where components render, not the Storybook application UI.
CSS-in-JS libraries in Storybook
CSS-in-JS libraries are designed to use basic JavaScript and often work in Storybook without extra configuration. Some libraries expect components to render in a specific rendering context (like providing themes), which can be accomplished with @storybook/addon-themes's withThemeFromJSXProvider decorator.
Add webfonts using preview-head.html
Webfonts can be made available by adding code to .storybook/preview-head.html. It is recommended to include assets with Storybook and configure the static file location.
Import fonts using fontsource in preview.ts
If using fontsource for fonts, you can import the needed CSS files in .storybook/preview.ts or .storybook/preview.tsx.
CSS in preview iframe, not Manager UI
Storybook injects CSS tags into the preview iframe where components render, not into the Storybook Manager UI.
Angular global styles in angular.json
For Angular, add global styles to the styles array in the angular.json file. This adds styles to the preview iframe where components render. Add the styles to both the storybook target and the build-storybook target in angular.json to ensure they are included in the static build.
Angular global styles configuration example
Example angular.json configuration with global styles in both storybook and build-storybook targets:
```json
{
"storybook": {
"builder": "@storybook/angular:start-storybook",
"options": {
"configDir": ".storybook",
"browserTarget": "angular-latest:build",
"compodoc": true,
"compodocArgs": ["-e", "json", "-d", "."],
"port": 6006,
"styles": [
"@angular/material/prebuilt-themes/indigo-pink.css",
"@fontsource/roboto/300.css",
"@fontsource/roboto/400.css",
"@fontsource/roboto/500.css",
"@fontsource/roboto/700.css",
"@fontsource/material-icons",
"src/styles.scss"
]
}
},
"build-storybook": {
"builder": "@storybook/angular:build-storybook",
"options": {
"configDir": ".storybook",
"browserTarget": "angular-latest:build",
"compodoc": true,
"compodocArgs": ["-e", "json", "-d", "."],
"styles": [
"@angular/material/prebuilt-themes/indigo-pink.css",
"@fontsource/roboto/300.css",
"@fontsource/roboto/400.css",
"@fontsource/roboto/500.css",
"@fontsource/roboto/700.css",
"@fontsource/material-icons",
"src/styles.scss"
],
"outputDir": "storybook-static"
}
}
}
```
Nx library styling configuration before version 14.1.8
For Nx libraries before version 14.1.8, configure styling in project.json using the @nrwl/storybook:build executor with a styles array to reference the application's styles.
Nx library styling configuration from version 14.1.8
Starting with Nx version 14.1.8, Nx uses the Storybook builder directly. When working with a library, configure the styling options (preprocessors) inside the build-storybook options configuration object. Nx will load Storybook's configuration and styling based on storybook.browserTarget.
Nx library styling configuration example from 14.1.8
Example workspace.json configuration for Nx library styling from version 14.1.8:
```json
{
"storybook": {
"executor": "@storybook/angular:start-storybook",
"options": {
"configDir": "apps/example-lib/.storybook",
"browserTarget": "example-lib:build-storybook"
}
},
"build-storybook": {
"executor": "@storybook/angular:build-storybook",
"outputs": ["{options.outputPath}"],
"options": {
"outputDir": "dist/storybook/example-lib",
"configDir": "apps/example-lib/.storybook",
"browserTarget": "example-lib:build-storybook",
"styles": [".storybook/custom-styles.scss"],
"stylePreprocessorOptions": {
"includePaths": ["libs/design-system/src/lib"]
}
}
}
}
```
Angular supports all Angular CLI CSS preprocessors
Storybook for Angular relies on the Angular CLI to build stories, so you can use any CSS preprocessor that the Angular CLI supports.
CSS modules support with Vite
Vite comes with CSS modules support out-of-the-box. If you have customized the CSS modules configuration in vite.config.js, it will automatically be applied to Storybook.
Import global CSS in preview.ts
To add global CSS for all your stories, import it in .storybook/preview.ts or .storybook/preview.tsx. These files will be subject to HMR (Hot Module Replacement), so you can see changes without restarting the Storybook server. This is the recommended approach for bundled CSS.
Include static CSS in preview-head.html
Global CSS files can be included in .storybook/preview-head.html for all stories. However, these files will not be subject to HMR, so you must restart the Storybook server to see changes.
CSS modules configuration with Webpack
If using Webpack and want to use CSS modules, you need extra configuration. Install @storybook/addon-styling-webpack to help configure these tools. For Next.js projects using @storybook/nextjs, CSS modules work without extra configuration since Storybook recreates the Next.js configuration.
PostCSS support with Vite
Vite comes with PostCSS support out-of-the-box. If you have customized the PostCSS configuration in vite.config.js, it will automatically be applied to Storybook.
PostCSS configuration with Webpack
If using Webpack and want to use PostCSS, you need extra configuration. Install @storybook/addon-styling-webpack to help configure these tools. For Next.js projects using @storybook/nextjs, PostCSS works without extra configuration.
CSS preprocessors support with Vite
Vite comes with Sass, Less, and Stylus support out-of-the-box.
CSS preprocessors configuration with Webpack
If using Webpack and want to use Sass or Less, you need extra configuration. Install @storybook/addon-styling-webpack to help configure these tools, or customize Storybook's webpack configuration yourself to include the appropriate loaders. For Next.js projects using @storybook/nextjs, Sass works without extra configuration.
storybook/theming module built with TypeScript
The `storybook/theming` module is built using TypeScript and includes TypeScript types as part of the package, which helps create valid themes for TypeScript users.
Built-in themes available
Storybook includes three built-in themes: light, dark, and normal. The normal theme matches your preferred color scheme. By default, Storybook uses the normal theme unless you specify otherwise.
Set Storybook theme in manager.js
To apply a theme to Storybook UI, modify `.storybook/manager.js` and import your theme, then pass it to the `addons.setConfig()` function. When setting a theme, you must set a complete theme object. The theme is replaced, not combined.
Docs theme separate from UI theme
Storybook Docs uses the same theme system as Storybook's UI but is themed independently from the main UI. The default theme for Docs is always the light theme, regardless of the main UI theme. To set a docs theme, configure it in `.storybook/preview.js`.
Create custom theme with create() function
The easiest way to customize Storybook is to use the `create()` function from `storybook/theming`. This function provides shorthands for the most common theme variables. Create a new file in your `.storybook` directory (e.g., `YourTheme.js`) and use `create()` to define your theme with a base theme and custom variables.
brandImage property for custom logo
The `brandImage` property in a theme allows you to replace Storybook's logo in the sidebar with your own. The `brandImage` property accepts any of the most common image formats.
base property is required in theme
The `base` property is required when creating a theme. Many other theme variables are optional, but `base` is not. The `base` property typically refers to using one of the built-in themes (light, dark, or normal) as your baseline.
CSS escape hatches for advanced styling
For fine-grained CSS control beyond the theming API, all UI and Docs components are tagged with class names. To style these elements, insert style tags into `.storybook/manager-head.html` for Storybook UI and `.storybook/preview-head.html` for Storybook Docs. This is an advanced feature and Storybook's inner HTML can change at any time through the release cycle.
MDX component overrides for docs
When using MDX for docs, you can override rendered components from Markdown using a `components` parameter in `.storybook/preview.js`. This allows you to insert custom renderers for elements like `code` blocks or Storybook block components such as `<Canvas />`. This is an advanced feature not officially supported by Storybook.
Theme support for addons
Some addons require specific theme variables. If sharing a theme with the community, support the official theme API and popular addons to ensure users have a consistent experience. For example, the Actions addon uses react-inspector which has its own themes that can be styled by supplying additional theme variables.
Theming engine uses emotion CSS-in-JS library
The Storybook theming engine relies on emotion, a CSS-in-JS library. Addon authors can reuse theme variables in styled components using either object notation or template literals.
SCSS include paths in Angular with Vite
SCSS search paths from the application's build target in angular.json are not inherited by Storybook. Configure them on the Storybook builder target using stylePreprocessorOptions. Both Angular-style includePaths and dart-sass/Vite spelling loadPaths are accepted, and paths are resolved relative to the workspace root.
SCSS paths with Angular builders configuration
Example in angular.json: 'storybook': { 'builder': '@storybook/angular-vite:start-storybook', 'options': { 'stylePreprocessorOptions': { 'includePaths': ['src/styles'] } } }
SCSS paths with Storybook CLI
When running through Storybook CLI (storybook dev / storybook build) rather than Angular builders, set SCSS search paths directly in .storybook/main.ts using viteFinal: async viteFinal(config) { const { mergeConfig } = await import('vite'); return mergeConfig(config, { css: { preprocessorOptions: { scss: { loadPaths: ['src/styles'] } } } }); }
Next.js font optimization support
Storybook supports next/font/google out of the box. For next/font/local, you must define the src property with a path relative to the directory where the font loader function is called. You must tell Storybook where the fonts directory is located via the staticDirs configuration, where the from value is relative to .storybook and the to value is relative to the project root.
Global Sass/SCSS stylesheets in Storybook
Global Sass/SCSS stylesheets are supported without additional configuration. Import them into the preview config file (.storybook/preview.tsx). Custom Sass configurations from next.config.js are automatically included.
CSS and Sass modules support
CSS modules and Sass/SCSS modules work as expected in Storybook for Next.js.
Styled JSX support
Styled JSX, the built-in CSS-in-JS solution for Next.js, is supported out of the box with zero configuration. Custom Babel configuration can be used via .babelrc or similar files to customize styled-jsx (e.g., adding @styled-jsx/plugin-sass).
Local images in next/image
Local images are supported in Storybook with next/image. Import an image file and pass it to the Image component. Width and height are automatically provided. The blurDataURL is set to equal the image itself for this framework. The placeholder blur option is optional.
Remote images in next/image
Remote images are supported in Storybook with next/image. Provide the image URL as the src prop and specify width and height explicitly.
next/font/google support
next/font/google is supported out of the box in Storybook with no additional configuration required.
next/font/local support and configuration
For next/font/local, you must define the src property. The path is relative to the directory where the font loader function is called. The Vite-based framework automatically handles font path mapping, so you don't need to configure staticDirs for fonts.
Unsupported next/font features
The following next/font features are not supported yet: font loaders configuration in next.config.js, fallback option, adjustFontFallback option, preload option (gets ignored, Storybook handles font loading its own way), and display option (gets ignored, all fonts are loaded with display set to 'block').
Mock Google Fonts to prevent build failures
It is highly recommended to mock Google Fonts requests during Storybook builds as fetching fonts from Google may fail and cause your pipeline to fail. Use the NEXT_FONT_GOOGLE_MOCKED_RESPONSES environment variable to reference a JavaScript module with mocked font responses. The module should export an object with Google Fonts URLs as keys and CSS font-face declarations as values.
Global Sass/SCSS stylesheets support
Global Sass/SCSS stylesheets are supported without any additional configuration. Import them into the preview config file. This automatically includes any custom Sass configurations in your Next.js config file.
CSS modules support
CSS modules work as expected in Storybook for Next.js with Vite.
Styled JSX support
Styled-jsx, the built-in CSS-in-JS solution for Next.js, is supported in Storybook for Next.js with Vite out of the box with zero config.
Tailwind CSS support
Tailwind in Next.js is supported via PostCSS. Storybook automatically handles the PostCSS config for you, including any custom PostCSS configuration, so you can import your global CSS directly into the preview config file.
PostCSS configuration handling
Next.js allows customizing PostCSS config, and Storybook automatically handles your PostCSS config for you.
Statically imported images won't load - troubleshooting
Make sure you are treating image imports the same way you treat them when using next/image in normal development. Image imports now work the 'Next.js way', returning an object with src, height, width, and blurDataURL properties instead of just the raw path. If something in Storybook isn't showing the image properly, ensure you expect the object to be returned from an import instead of only the asset path.
Install sharp for image optimization
If you see the error 'You are importing avif images, but you don't have sharp installed', you need to install sharp in your project. Sharp is a dependency of Next.js's image optimization feature: npm install sharp, yarn add sharp, or pnpm add sharp.
Import application CSS in preview for styles in TanStack React
If styles are missing in Storybook with TanStack React, import your application CSS in .storybook/preview.* so it is bundled with the preview. For example: import '../src/styles/app.css';
CSS configuration needed for component styles
Storybook is not opinionated about how CSS is generated or loaded. It renders whatever DOM elements are provided, but you may need to configure CSS tooling for Storybook's rendering environment. Setup guides exist for popular tools including Tailwind, Material UI, Vuetify, Styled Components, Emotion, Sass, Bootstrap, Less, and Vanilla-extract.