.stories.ts file with realistic demo data. Storybook is automatically deployed to GitHub Pages on pushes to main.
Running Storybook
http://localhost:6006 to browse the component library.
npm run dev:storybook starts all three servers concurrently: Astro (port 4321), Sanity Studio (port 3333), and Storybook (port 6006). Use this when developing new blocks so you can preview them in both the CMS context and in isolation.Setup
Storybook uses thestorybook-astro renderer with @storybook/builder-vite. The configuration lives in astro-app/.storybook/:
main.ts highlights
The Storybook Vite config includes several custom plugins to make Astro components render correctly outside the Astro build pipeline:astroAssetsStub()— Replacesastro:assetswith a plain<img>component so the Astro image service is not loaded.astroVirtualModuleStubs()— Stubsvirtual:astro-icon,sanity:client,astro:actions, and Astro font virtual modules. Loads real Lucide and Simple Icons data from@iconify-jsonpackages so icons render.lucideStaticSvgStub()— Interceptslucide-staticSVG imports and provides inline SVG Astro components, bypassing Astro’s image service.tailwindcss()— Injects Tailwind CSS v4 via the Vite plugin so all utility classes apply in Storybook.
../src/**/*.stories.@(js|jsx|ts|tsx)
preview.ts
global.css import ensures Tailwind CSS v4 variables and theme tokens apply to all stories.
Story file conventions
Every custom block insrc/components/blocks/custom/ has a co-located .stories.ts file. Stories use the Component Story Format (CSF) with inline args that match the block’s flat props interface.
Story file structure
titlefollows the'Category/BlockName'pattern (e.g.,'Blocks/HeroBanner').tags: ['autodocs']generates an automatic documentation page from the component’s prop types.argsuse the same flat props the block receives via<Component {...block} />.- Include
_typeand_keyin args — blocks expect these Sanity-standard fields. - Export at least two stories per block:
Defaultand a variant (e.g.,Minimal,Dark,WithImage).
Custom blocks with stories
All custom blocks insrc/components/blocks/custom/ have Storybook stories:
HeroBanner
Heading, subheading, CTA buttons, optional background image carousel. Stories cover default layout and minimal variants.
FeatureGrid
Icon/image + title + description cards. Stories show different column counts and icon styles.
SponsorCards
Sponsor documents with tier badges. Stories use mock sponsor data matching the Sanity schema shape.
FaqSection
Expandable question/answer pairs with keyboard accessibility. Stories cover full FAQ sets and minimal two-item variants.
CtaBanner
Heading, description, and action buttons. Stories demonstrate light and dark background variants.
StatsRow
Stat cards with heading and dark/light variant support. Stories show numeric and percentage stats.
RichText
Portable Text renderer with inline images and callout boxes. Stories use serialized Portable Text arrays.
TextWithImage
Portable text content alongside a positioned image. Stories cover left/right image placement.
src/components/ui/ alongside their component files:
button/button.stories.tsbadge/badge.stories.tsavatar/avatar.stories.tsaccordion/accordion.stories.ts
*Story.astro wrapper files (ButtonStory.astro, etc.) that pre-populate slots so Storybook can render them without JSX.
Deployed Storybook
Storybook builds and deploys to GitHub Pages automatically via.github/workflows/deploy-storybook.yml on every push to main that touches component files. The workflow can also be triggered manually from the Actions tab.
The deployed Storybook is the canonical component reference for the project — it shows every block with realistic data and both light/dark background options.
Integration tests for Storybook
The integration test filetests/integration/storybook-1-4.test.ts validates the Storybook setup without running a browser:
.storybook/main.tsconfiguresstorybook-astroframework.storybook/preview.tsimportsglobal.css- All custom block story files exist and have a default export,
title,component, and at least one named story - UI primitive story files and
*Story.astrowrappers exist package.jsonhasstorybookandbuild-storybookscriptsstorybook buildsucceeds and produces a validiframe.html(> 1 KB — not an empty chunk)
Dependencies
| Package | Purpose |
|---|---|
storybook | Core Storybook framework |
storybook-astro | Astro component renderer for Storybook |
@storybook/addon-docs | Auto-generated docs from prop types and JSDoc |
@storybook/builder-vite | Vite build pipeline for Storybook |