

astro-reactflow 0.5.0

@sjohansson/astro-reactflow 0.5.0 went out on 8
September 2026. It is one fix, but it is the kind that makes the package look broken: diagrams rendered as an empty box.
If you use the component, upgrade. If you have not seen it before, the intro post covers the
basics.
The bug
You would drop a <ReactFlowWrapper> on a page, build the site, and get the title bar, the footer, and nothing in
between. No nodes, no edges, no error in the console. React Flow had rendered everything. It had just rendered it into a
box 0px high. Bit of a bugger to track down.
The cause is how Astro collects CSS. It walks the server module graph for each page and emits every stylesheet it finds
there. The wrapper has to be used with client:only="react", because React Flow measures the DOM and has no server
output. client:only means Astro never imports the component on the server. So the component’s own
import "./styles.css" never made it into the graph Astro looks at, and the stylesheet was silently dropped from the
build.
Without that stylesheet there is no flex: 1 1 auto; min-height: 0 on .reactflow-pane, the pane collapses, and the
canvas inside it has nothing to be 100% of.
I hit this on this very blog. The workaround was a copy of the package’s stylesheet pasted into the site CSS with a “TEMPORARY” comment on top. It works, but it drifts the moment the package changes, and nobody else using the package would know to do it.
The fix: the integration injects the styles
The integration now calls injectScript("page-ssr", ...) with two bare imports:
if (injectStyles) {
injectScript(
"page-ssr",
`import "@xyflow/react/dist/style.css";
import "@sjohansson/astro-reactflow/styles.css";`,
);
}
A page-ssr script runs as part of every page’s server render, so its imports land in the server graph and Astro emits
and links the CSS like any other stylesheet. The specifiers are bare so they resolve from your project. @xyflow/react
is a peer dependency, so it lives there, not inside the package.
If you already have the integration registered, there is nothing to change:
// astro.config.mjs
import { defineConfig } from "astro/config";
import reactFlow from "@sjohansson/astro-reactflow/integration";
export default defineConfig({
integrations: [reactFlow()],
});
Registering the integration is now what gets the CSS onto the page. If you skipped it and added react() yourself,
your diagrams are still an empty box. Add reactFlow() or import the stylesheets by hand, as below.
A public stylesheet export
Injecting the CSS means every page gets it, diagrams or not. The files are small, so for most sites that is fine. If you would rather keep them off pages without diagrams, turn injection off and import the CSS where you need it:
integrations: [reactFlow({ injectStyles: false })],
---
import "@xyflow/react/dist/style.css";
import "@sjohansson/astro-reactflow/styles.css";
---
The second import is new. Before 0.5 there was no way to write it. The build emitted the stylesheet as
dist/assets/styles-<hash>.css, and it was not in the exports map, so a manual import had nothing to point at. Now it
builds to a stable dist/styles.css and package.json exports it:
"exports": {
"./styles.css": "./dist/styles.css"
}
That also makes it easy to reference from a layout or a global stylesheet, and to see in a diff when it changes.
Upgrading
pnpm update @sjohansson/astro-reactflow
Then check you have reactFlow() in your integrations, and delete any hand-copied wrapper CSS you added to get around
the bug. Your --arf-* overrides on .reactflow-wrapper carry on as before.
If you are coming from something older than 0.4.2, the releases in between only widened peer ranges: Astro 5 to 7 and
@astrojs/react 4 to 6. No code changes needed for those.