Server side rendering, server side generation
This is an advanced use case and assumes you are already familiar with SvelteFlow. If you’re new to SvelteFlow, check out our getting started guide.
In this guide, you’ll learn how to configure SvelteFlow for server-side rendering, enabling you to:
- Generate static HTML diagrams for documentation
- Render SvelteFlow diagrams in non-JavaScript environments
- Create dynamic Open Graph images for social media sharing
(For client-side image generation, check out our download image example.)
Why Server-Side Rendering is Complex
To understand why server-side rendering in Svelte Flow requires special configuration, let’s look at what SvelteFlow typically handles on the client side:
-
Node Dimension Calculation
- Nodes can contain any content, so their dimensions are determined by the browser’s layout engine
- This dynamic sizing isn’t available during server-side rendering
-
Handle Position Detection
- Edge connections require precise handle positions
- These positions are calculated based on CSS layout, which isn’t available on the server
-
Container Size Adaptation
- SvelteFlow adapts to its container’s dimensions
- Server-side rendering needs explicit dimensions
Node Dimensions
The most crucial aspect of server-side rendering is specifying node dimensions. On the client, SvelteFlow automatically measures nodes and stores dimensions in measured.width
and measured.height
. For server-side rendering, you must provide these dimensions explicitly using either:
width
andheight
: Static dimensions that won’t changeinitialWidth
andinitialHeight
: Dynamic dimensions that may change after client-side hydration
<script>
const nodes = [
{
id: '1',
type: 'default',
position: { x: 0, y: 0 },
data: { label: 'Node 1' },
width: 100,
height: 50,
},
];
</script>
Handle Positions
To render edges on the server, you need to provide handle positions explicitly. On the client, SvelteFlow calculates these positions automatically, but for server-side rendering, you must specify them using the handles
property:
<script>
import { Position } from '@xyflow/svelte';
const nodes = [
{
id: '1',
type: 'default',
position: { x: 0, y: 0 },
data: { label: 'Node 1' },
width: 100,
height: 50,
handles: [
{
type: 'target',
position: Position.Top,
x: 100 / 2,
y: 0,
},
{
type: 'source',
position: Position.Bottom,
x: 100 / 2,
y: 50,
},
],
},
];
</script>
Using fitView
with Server-Side Rendering
If you know your container’s dimensions, you can use fitView
during server-side rendering by providing the container’s width and height:
<script>
import { SvelteFlow } from '@xyflow/svelte';
let nodes = $state.raw([/* ... */]);
let edges = $state.raw([/* ... */]);
</script>
<SvelteFlow {nodes} {edges} fitView width={1000} height={500} />
Generating Static HTML
To create static HTML output, you can use Svelte’s server-side rendering capabilities. This generates an HTML string that you can use for static files or HTTP responses:
<script>
import { SvelteFlow, Background } from '@xyflow/svelte';
import { render } from 'svelte/server';
function toHTML({ nodes, edges, width, height }) {
const { html } = render(SvelteFlow, {
props: {
nodes,
edges,
width,
height,
minZoom: 0.2,
fitView: true,
},
children: [Background],
});
return html;
}
</script>