Dev Mode Rendering
In dev mode (storybook dev), Astro components are rendered on-demand through a request cycle between the browser and the Vite dev server.
Step-by-step flow
Section titled “Step-by-step flow”-
Story definition — Stories import Astro components and define variations with different props and slots.
-
Component detection — The renderer checks imported components for the
isAstroComponentFactoryflag to identify Astro components. -
Server rendering — When an Astro component is detected, a render request is sent to the Vite dev server middleware via HMR (Hot Module Replacement).
-
Container rendering — The middleware uses Astro’s Container API to render the component with the provided props and slots. The
patchCreateAstroCompatwrapper bridges the Astro compiler v2/v3 calling convention difference. -
HTML injection — The rendered HTML string is sent back to the client and injected into Storybook’s canvas.
-
Hydration — Client-side scripts are re-executed to add interactivity. This handles framework islands (e.g. React components inside Astro with
client:load) and Alpine.js directives. -
Style application — Scoped styles from
.astrocomponents are applied. In Astro 6, style sub-module imports (?astro&type=style&index=N&lang.css) are generated by the component marker plugin. -
Framework delegation — For non-Astro framework components (React, Solid, Vue, etc.), the renderer delegates directly to the framework-specific
renderToCanvasbefore callingstoryFn(). This ordering is critical — it lets reactive frameworks like Solid manage their own rendering lifecycle without orphaned effects. -
HMR updates — Changes to components trigger re-renders. The Vite HMR event listeners in
render.tsxhandle updates while preserving state when possible.
The Vite HMR channel
Section titled “The Vite HMR channel”Communication between the browser and server uses Vite’s built-in HMR channel:
- Client side (
render.tsx): Sendsastro:render:requestevents with the component module ID, props, and slots - Server side (
viteStorybookAstroMiddlewarePlugin.ts): Listens for requests, invokes the Container API, and responds withastro:render:responsecontaining the rendered HTML
This approach avoids additional HTTP endpoints and reuses Vite’s existing WebSocket connection.