Server Side Rendering

Advanced · 11 min read · Updated Nov 10, 2026

SSR and SSG: A Complete Guide to Server-Side Rendering Node-Based Diagrams

React Flow is widely used to build interactive node-based applications, workflow editors, visual programming tools, and diagram builders. However, not every application needs to render its diagrams exclusively in the browser.

Sometimes you need to display a workflow diagram in a documentation page, generate a preview image for social sharing, or render a diagram as static HTML. This is where Server-Side Rendering (SSR) and Static Site Generation (SSG) become useful.

React Flow supports server-side rendering starting from version 12. With the right configuration, developers can render nodes and edges on the server without relying on browser-based measurements.

In this guide, we will explore how React Flow SSR works, how to configure node dimensions and handle positions, how to render static HTML, and how to integrate server-rendered diagrams into modern React applications.

What Is Server-Side Rendering in React Flow?

Server-Side Rendering is a technique where a React application generates HTML on the server before sending it to the browser.

In a traditional client-side React Flow application, the browser renders the nodes, measures their dimensions, calculates handle positions, and displays the connected edges.

With React Flow SSR, the server receives enough layout information to render the diagram before the browser loads the application.

This makes it possible to:

  • Display static workflow diagrams in documentation.
  • Render React Flow diagrams in environments without JavaScript.
  • Generate HTML previews of node-based applications.
  • Create dynamic Open Graph images and social sharing previews.
  • Improve the initial rendering experience for diagram-heavy pages.

For example, a workflow builder might allow users to share a public link to a workflow. Instead of showing an empty preview while the application loads, the server can generate a visual representation of the workflow.

SSR vs. SSG: What Is the Difference?

Although Server-Side Rendering and Static Site Generation are closely related, they serve different purposes.

FeatureServer-Side Rendering (SSR)Static Site Generation (SSG)
Rendering timeWhen a request is handledDuring the build process
HTML outputGenerated dynamicallyGenerated ahead of time
DataCan use request-time dataUsually uses build-time data
Best forFrequently changing diagramsDocumentation and fixed previews
PerformanceDepends on server executionCan be served as static files

Both approaches can be useful for React Flow applications.

For example, a workflow dashboard that displays frequently updated diagrams may benefit from SSR. A documentation website containing predefined architecture diagrams may be better suited to SSG.

The important requirement is that React Flow receives the dimensions and layout information needed to render the diagram without browser measurements.

1. Configure Node Dimensions for Server-Side Rendering

One of the most important requirements for React Flow SSR is defining node dimensions.

In a browser, React Flow can measure node elements and determine their width and height automatically. These measurements are normally stored in measured.width and measured.height.

However, the server cannot measure DOM elements in the same way.

Therefore, React Flow needs explicit dimension information before it can render nodes on the server.

There are two properties you can use:

  • width and height
  • initialWidth and initialHeight

Using width and height

Use width and height when your node dimensions are fixed and already known.

import { ReactFlow, type Node } from '@xyflow/react';
import '@xyflow/react/dist/style.css';

const nodes: Node[] = [
  {
    id: '1',
    type: 'default',
    position: { x: 0, y: 0 },
    data: { label: 'Node 1' },
    width: 150,
    height: 60,
  },
];

function FlowPreview() {
  return (
    <div style={{ width: 1000, height: 500 }}>
      <ReactFlow
        nodes={nodes}
        edges={[]}
        fitView
      />
    </div>
  );
}

Here, the node has a predefined width of 150 pixels and a height of 60 pixels.

React Flow can use these dimensions to render the node without waiting for browser measurement.

Using initialWidth and initialHeight

Not every custom node has fixed dimensions. Some nodes may have different sizes depending on their content.

For these situations, you can use initialWidth and initialHeight.

const nodes: Node[] = [
  {
    id: '1',
    type: 'default',
    position: { x: 0, y: 0 },
    data: {
      label: 'Dynamic Content Node',
    },
    initialWidth: 200,
    initialHeight: 100,
  },
];

These properties provide dimensions for the initial render. Once React Flow measures the node on the client, the measured dimensions can take over.

When should you use each property?

PropertyRecommended use
width and heightFixed dimensions that should remain consistent
initialWidth and initialHeightInitial dimensions for nodes that may change size

If your application contains dynamic custom nodes, initial dimensions can make server-rendered previews possible while allowing the client to measure the actual content later.

2. Configure Handle Positions for Server-Side Edge Rendering

Rendering nodes is only part of the process. If your diagram contains edges, React Flow also needs to know where the connection handles are located.

In a client-side application, React Flow measures the positions of handles inside each node.

On the server, those browser measurements are unavailable.

To solve this, React Flow allows you to provide handle information through the handles property of a node.

Consider the following example:

import {
  Position,
  type Node,
} from '@xyflow/react';

const nodes: Node[] = [
  {
    id: '1',
    type: 'default',
    position: { x: 0, y: 0 },
    data: { label: 'Node 1' },
    width: 150,
    height: 60,
    handles: [
      {
        type: 'target',
        position: Position.Top,
        x: 75,
        y: 0,
      },
      {
        type: 'source',
        position: Position.Bottom,
        x: 75,
        y: 60,
      },
    ],
  },
];

This node has two handles:

  • A target handle positioned at the top.
  • A source handle positioned at the bottom.

The x and y properties define the handle's position relative to the node.

React Flow can use this information to calculate the edge paths during server rendering.

Why are handle positions important?

Imagine a workflow with three connected nodes:

  1. Input Node
  2. Processing Node
  3. Output Node

Each node contains connection handles. Without their positions, the server cannot accurately determine where the edges should begin and end.

Providing handle information allows React Flow to render the connected diagram before the browser performs its own measurements.

If your goal is to render only the nodes without edges, you can skip the handles property.

3. Use fitView During Server-Side Rendering

A workflow diagram may contain multiple nodes distributed across a large canvas.

If you render the diagram without configuring its viewport, some nodes may appear outside the visible area.

React Flow provides the fitView property to automatically adjust the viewport so that all nodes fit inside the available container.

For server-side rendering, you also need to provide the dimensions of the React Flow container.

import { ReactFlow } from '@xyflow/react';

function ServerRenderedFlow() {
  return (
    <ReactFlow
      nodes={nodes}
      edges={edges}
      width={1000}
      height={500}
      fitView
    />
  );
}

Here:

  • width defines the container width.
  • height defines the container height.
  • fitView calculates a viewport that includes the nodes.

React Flow can calculate the required viewport transformation on the server and include it in the rendered output.

This is particularly useful when generating workflow previews or embedding diagrams in static pages.

4. Configure SSR with ReactFlowProvider

Some React Flow applications use ReactFlowProvider to share flow state across multiple components.

The provider can also receive initial node and edge information, along with the dimensions of the flow container.

import {
  ReactFlowProvider,
} from '@xyflow/react';

function App() {
  return (
    <ReactFlowProvider
      initialNodes={nodes}
      initialEdges={edges}
      initialWidth={1000}
      initialHeight={500}
      fitView
    >
      <FlowEditor />
    </ReactFlowProvider>
  );
}

The initialNodes, initialEdges, initialWidth, and initialHeight properties provide the information required for the initial render.

The initial prefix is important: these values are used to initialize the provider. After initialization, the provider manages the flow state through its context.

This approach is useful when your application has multiple components that need access to the same React Flow instance.

For example, a workflow editor might contain:

  • A main canvas.
  • A custom toolbar.
  • A node configuration panel.
  • A workflow navigation component.

Using the provider makes it easier to share flow-related state and functionality across these components.

5. Generate Static HTML from React Flow

One of the most useful applications of React Flow SSR is generating static HTML.

React provides a function called renderToStaticMarkup() through react-dom/server. It converts a React component into an HTML string.

You can use this function to generate a static representation of a React Flow diagram.

import React from 'react';
import { renderToStaticMarkup } from 'react-dom/server';

import {
  ReactFlow,
  Background,
} from '@xyflow/react';

import '@xyflow/react/dist/style.css';

function toHTML({ nodes, edges, width, height }) {
  const html = renderToStaticMarkup(
    React.createElement(
      ReactFlow,
      {
        nodes,
        edges,
        width,
        height,
        minZoom: 0.2,
        fitView: true,
      },
      React.createElement(Background, null),
    ),
  );

  return html;
}

The function receives the workflow data and container dimensions, renders the React Flow component, and returns the generated HTML.

You can then use the HTML string to:

  • Create a static HTML file.
  • Include a diagram in generated documentation.
  • Send rendered markup as an HTTP response.
  • Build static previews for workflow pages.

Remember that static HTML does not automatically include the interactive React application. It represents the rendered output, not a fully interactive editor.

Also, include the appropriate CSS in the page where the generated HTML is displayed. If your custom nodes depend on external styles, those styles must be included as well.

6. Use React Flow SSR in Next.js Applications

Next.js supports multiple rendering strategies, including Server Components, server-side rendering, and static generation.

React Flow can be integrated into these applications, but it is important to distinguish between rendering a static diagram and running an interactive workflow editor.

An interactive React Flow editor depends on browser functionality such as DOM measurements, pointer events, and user interactions. A static server-rendered diagram can instead be generated using the SSR configuration described above.

A practical architecture is to separate the two responsibilities:

Server-rendered diagram preview

  • Loads workflow data.
  • Defines node dimensions and handle positions.
  • Generates the initial HTML representation.
  • Displays a static workflow preview.

Client-side workflow editor

  • Handles dragging and connecting nodes.
  • Updates node and edge state.
  • Supports zooming, panning, and selection.
  • Manages interactive custom components.

For a Next.js application, you can keep the interactive editor in a client component:

'use client';

import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';

export default function WorkflowEditor({
  nodes,
  edges,
}) {
  return (
    <div style={{ width: '100%', height: 600 }}>
      <ReactFlow
        nodes={nodes}
        edges={edges}
        fitView
      />
    </div>
  );
}

The server can prepare the workflow data and pass it to the client component.

For static pages, you can generate the diagram markup separately using renderToStaticMarkup().

This separation helps keep server-rendered previews lightweight while preserving the full functionality of the browser-based editor.

7. Common Challenges When Using React Flow SSR

Server-side rendering introduces a few requirements that developers should consider when designing their node-based applications.

Missing node dimensions

If a node does not have dimensions available for the initial server render, React Flow cannot render it correctly.

Solution: Provide width and height or initialWidth and initialHeight.

Missing handle positions

Edges may not render correctly when the server does not know where the handles are located.

Solution: Define the node's handles property when server-rendered edges are required.

Incorrect viewport dimensions

A diagram may render outside the visible area if its container dimensions are unknown.

Solution: Provide the React Flow container's width and height when using server-side fitView.

Static HTML is not interactive

A generated HTML string does not automatically include React event handlers or interactive editor functionality.

Solution: Use static markup for previews and documentation. Mount an interactive React Flow application on the client when editing is required.

Custom styles are missing

A static HTML representation may look different if the styles used by React Flow or custom nodes are not included in the destination page.

Solution: Include the required React Flow stylesheet and your application's custom CSS.

8. Best Practices for React Flow SSR and SSG

For reliable server-rendered diagrams, follow these recommendations:

  1. Define node dimensions: Make sure every server-rendered node has the dimensions it needs.
  2. Configure handle positions: Provide handle metadata when edges must appear in the initial HTML.
  3. Set container dimensions: Use known width and height values for server-side viewport calculations.
  4. Separate previews from editors: Keep static rendering and interactive functionality as distinct responsibilities.
  5. Use predictable node structures: Maintain consistent node and edge data across server and client rendering.
  6. Include the required styles: Ensure the rendered markup has access to the correct CSS.
  7. Test hydration: If the server-rendered output is later hydrated into an interactive React application, ensure the initial server and client output are consistent.

These practices help prevent rendering issues and make React Flow applications easier to maintain.

9. When Should You Use React Flow SSR?

Not every React Flow application needs server-side rendering. It is most useful when the initial diagram representation must be available before client-side JavaScript runs.

Use caseSSR/SSG benefit
Documentation websitesDisplay diagrams as part of static content
Workflow sharingGenerate previews for shared workflow links
SaaS dashboardsRender initial workflow representations
Open Graph previewsCreate visual previews for social sharing
Static reportsInclude diagrams in generated HTML
Public workflow galleriesDisplay diagrams without requiring an interactive editor

For applications that only need users to create and edit diagrams in the browser, traditional client-side rendering may be sufficient.

Choose SSR or SSG based on how and where the diagram needs to be displayed.

10. Build Advanced React Flow Applications with VisualFlow

Building a production-ready node-based application involves more than rendering nodes and edges. Developers also need to consider custom node structures, connection handles, workflow layouts, state management, and interactive editing experiences.

VisualFlow provides React Flow examples and ready-to-use templates that help developers explore different approaches to building visual applications.

Explore VisualFlow to discover examples for:

  • AI workflow builders
  • Automation workflow editors
  • Custom node-based interfaces
  • Nested and grouped diagrams
  • Interactive data visualization
  • Advanced edge and connection designs

Whether you are developing a workflow editor, an AI agent builder, or a custom diagramming application, VisualFlow can provide practical implementation references and inspiration.

Visit VisualFlow to explore React Flow examples and templates.

Conclusion

Server-Side Rendering and Static Site Generation make it possible to use React Flow beyond traditional browser-based editors.

By configuring node dimensions, defining handle positions, providing container dimensions, and using React's renderToStaticMarkup() function, developers can generate server-rendered diagrams and static HTML representations.

These capabilities are particularly useful for documentation, workflow previews, public diagram galleries, and social sharing.

The key is to provide React Flow with the layout information that the browser would normally calculate. Once that information is available, you can build applications that combine server-rendered diagrams with powerful client-side editing experiences.