DEV Community

Ondrej Machala
Ondrej Machala

Posted on

Storybook Screenshots Go Stale the Day You Take Them

You finished your component library. You took beautiful screenshots of every component for the docs. Button variants, form states, card layouts. Looked great.

Then someone changed the border radius token from 4px to 8px. Every screenshot is now wrong. Nobody updates them because there are 40 of them and the process is: open Storybook, find the story, resize the browser, take screenshot, crop it, save it, commit.

So the docs show components that look slightly different from reality. Users notice. Trust erodes.

Automate the screenshots

Point your screenshot automation at your Storybook instance:

{
  "screenshots": [
    {
      "name": "button-primary",
      "url": "http://localhost:6006/iframe.html?id=components-button--primary",
      "selector": "#storybook-root > *"
    },
    {
      "name": "button-secondary",
      "url": "http://localhost:6006/iframe.html?id=components-button--secondary",
      "selector": "#storybook-root > *"
    },
    {
      "name": "card-default",
      "url": "http://localhost:6006/iframe.html?id=components-card--default",
      "selector": "#storybook-root > *"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The trick is using the /iframe.html URL instead of the full Storybook UI. This gives you just the component, no sidebar or toolbar.

Run npx heroshot and all 40 screenshots regenerate.

After every design token change

Add it to your CI pipeline:

- name: Build Storybook
  run: npx storybook build --output-dir storybook-static

- name: Serve Storybook
  run: npx serve storybook-static -p 6006 &

- name: Update screenshots
  run: npx heroshot
Enter fullscreen mode Exit fullscreen mode

Now every PR that changes a design token also updates the screenshots. Reviewers see the visual diff right in the PR.

Dark mode variants

If your component library supports theming:

{
  "name": "button-primary",
  "url": "http://localhost:6006/iframe.html?id=components-button--primary&globals=theme:dark",
  "selector": "#storybook-root > *"
}
Enter fullscreen mode Exit fullscreen mode

Or let heroshot capture both automatically by omitting the color scheme. It'll produce button-primary-light.png and button-primary-dark.png.

The visual picker shortcut

Don't want to write JSON by hand? Navigate visually:

npx heroshot config
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:6006/iframe.html?id=components-button--primary in the picker, click the component, done. The selector and URL are captured for you.

40 components, 40 clicks, one config file. Every future update is just npx heroshot.

Top comments (0)