Storybook from CI — designers get a link, not a checkout
A component change shouldn't need 'pull the branch, npm install, npm run storybook' to get reviewed. Publish the static build from CI and every PR carries a live component library the whole team can click through.
The artifact dead-end
Design review over screenshots in PR comments is lossy: no states, no viewports, no interactions. And hosted Storybook platforms charge per seat for what is, at its core, a static folder.
storybook-static/ is already a complete website. It doesn't need a platform — it needs a URL.
Two lines to a live link
Generate the report like you already do, then hand the folder to the action:
Build the static Storybook
npm run build-storybook.github/workflows/ci.yml
- uses: bitgate/ship-page-action@v1
if: always()
with:
path: storybook-static/Omit path entirely and the action auto-detects storybook-static/ on its own. The URL lands in the job summary — add comment: true and it lands on the pull request too.
What you get
- Full interactivity — controls, actions, viewport switching — because the static build is served untouched
- Per-PR URLs with name: pr-${{ github.event.number }} mean every push refreshes the same review link
- comment: true posts the link as a sticky PR comment, so design feedback happens where the code review already is
Questions
How is this different from Chromatic?
Chromatic is a full visual-testing platform — if you need snapshot diffing, use it. If you need the built Storybook on a URL per PR, this is two lines of YAML and no per-seat pricing.
Does it work with Vite-built Storybooks?
Yes — anything that produces storybook-static/ works: React, Vue, Svelte, Web Components, webpack or Vite builders.
Can the Storybook stay up permanently?
On a paid plan, set ttl to never expire and use a named drop — your main-branch Storybook gets a permanent URL you can link from the README.
Try it on your next run
Anonymous deploys need no account and no key — paste the step, get a link. When you want stable URLs that redeploy in place, an API key and a name are all it takes.