Navigation

Integrations

Set up Master CSS in Storybook

Load application styles into the Storybook preview iframe and verify development and production stories with the Vite builder.

On this page

Use the application’s CSS entry in Storybook’s preview iframe, where stories render. Start from an application that already uses Master CSS and has Storybook installed. This recipe uses React, the Vite builder and Master CSS static mode. Set up the application with the Vite integration first. Other Vite-based frameworks use their own Storybook package and story syntax.

#Import the shared CSS entry

Storybook’s Vite builder normally reads the application’s Vite configuration. Keep masterCSS() registered there once, then import the application stylesheet from .storybook/preview.ts. Preserve existing preview decorators and parameters.

The import styles stories inside the preview iframe. It does not style Storybook’s sidebar or toolbar.

.storybook/preview.ts
import type { Preview } from '@storybook/react-vite'import '../src/index.css'const preview: Preview = {  parameters: {},}export default preview

#Verify an actual story

Keep the application's @import '@master/css'; in src/index.css. Create this story within the configured story glob; its complete class names become part of the static CSS build:

Check the installed styles

src/MasterCSS.stories.tsx
import type { Meta, StoryObj } from '@storybook/react-vite'const meta = { title: 'Master CSS/Installation' } satisfies Metaexport default metatype Story = StoryObj<typeof meta>export const Check: Story = {  render: () => (    <p id="master-check" className="w-fit m(0) p-md b-solid b(1) b-line-divider r-md text-sm font-regular bg-surface-raised fg-text-strong">      Hello World    </p>  )}
A neutral surface, a fine border, small corners and 1rem of padding on every side.

Run npm run storybook and open Master CSS / Installation / Check. The paragraph should have a raised surface, rounded corners and 1rem padding. Change p-md to p-lg in the story: padding should grow to 1.5rem. Restore it, then build the production preview:

npm run build-storybook

Serve storybook-static with an HTTP server and open the same story. Inspect its preview iframe, not the manager document: the stylesheet and paragraph live in that separate document. Static mode generates the CSS ahead of time; Storybook still needs JavaScript to render stories.

If the app is styled but stories are not, first check the CSS import in preview.ts, then confirm the Master CSS plugin runs in Storybook’s builder. With static rendering, keep complete class strings in story source or add the story directory to @source when it lies outside the application’s scanned files.

#Register a separate Vite integration when needed

If your Storybook configuration deliberately does not load the application’s Vite configuration, register Master CSS in viteFinal. Merge this into your existing configuration, retaining its story globs, addons and framework settings. Skip this registration when the application plugin is already loaded.

.storybook/main.ts
import type { StorybookConfig } from '@storybook/react-vite'const config: StorybookConfig = {  framework: '@storybook/react-vite',  stories: ['../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],  async viteFinal(config) {    const { mergeConfig } = await import('vite')    const { default: masterCSS } = await import('@master/css-vite')    return mergeConfig(config, {      plugins: [        masterCSS()      ]    })  }}export default config

Use the matching Storybook package for your framework and builder. The viteFinal hook applies to the Vite builder; a Webpack-based Storybook needs its own Webpack integration.