Back to Blog

Tutorial: Implementing React Flow in Sanity Studio for Interactive and Editable Flow Diagrams

April 10, 2026
reactflowsanitynextjsportable-textdiagram
Tutorial: Implementing React Flow in Sanity Studio for Interactive and Editable Flow Diagrams

Implementing React Flow in Sanity Studio

This article explains how to implement React Flow in Sanity Studio to build interactive and editable flow diagrams. The workflow is reproducible for other developers and includes schema setup, custom input, and frontend rendering for case study pages.

Prerequisites

  • A Next.js project using the App Router.
  • Sanity Studio integrated under an admin route.
  • The @xyflow/react package installed.

Implementation Algorithm

  1. Define node and edge schemas in Sanity so the graph is stored as structured data.
  2. Create a React Flow-based custom input component to add, drag, and connect nodes.
  3. Sync editor changes to architectureGraph using Sanity form patch operations.
  4. Render the graph in the case study frontend for desktop and mobile layouts.
  5. Backfill legacy case studies with architectureGraph so all documents are editable in Studio.

Snippet: Graph Schema in Sanity

src/sanity/schemaTypes/architectureGraph.ts
import {defineArrayMember, defineField, defineType} from 'sanity'

export const architectureGraphType = defineType({
  name: 'architectureGraph',
  title: 'Architecture Graph',
  type: 'object',
  fields: [
    defineField({
      name: 'nodes',
      type: 'array',
      of: [defineArrayMember({type: 'architectureGraphNode'})],
      validation: (Rule) => Rule.required().min(1),
    }),
    defineField({
      name: 'edges',
      type: 'array',
      of: [defineArrayMember({type: 'architectureGraphEdge'})],
    }),
  ],
})

Snippet: React Flow Custom Input in Studio

src/sanity/components/ArchitectureGraphInput.tsx
import {ReactFlow, useNodesState, useEdgesState, addEdge} from '@xyflow/react'
import {set, type ObjectInputProps} from 'sanity'

export default function ArchitectureGraphInput(props: ObjectInputProps<any>) {
  const [nodes, setNodes, onNodesChange] = useNodesState([])
  const [edges, setEdges, onEdgesChange] = useEdgesState([])

  return (
    <ReactFlow
      nodes={nodes}
      edges={edges}
      onNodesChange={onNodesChange}
      onEdgesChange={onEdgesChange}
      onConnect={(connection) =>
        setEdges((current) => addEdge({...connection, type: 'smoothstep', animated: true}, current))
      }
      fitView
      nodesDraggable
      panOnDrag
    />
  )
}

// Sync changes back to Sanity when nodes/edges update
// props.onChange(set({nodes, edges}))

Snippet: Render Graph in Case Study

src/components/LiveArchitecture.tsx
<ReactFlow
  nodes={renderedNodes}
  edges={renderedEdges}
  fitView
  fitViewOptions={isMobile
    ? {padding: 0.24, minZoom: 0.74, maxZoom: 1}
    : {padding: 0.16, minZoom: 0.68, maxZoom: 1}
  }
  nodesDraggable
  panOnDrag
  panOnScroll={!isMobile}
/>

Official References

React Flow Documentation

Sanity Studio Documentation