File: workflow.md | Updated: 11/15/2025
Slash Forward
Docs Cookbook Providers Playground AI ElementsAI ElementsLeft sparkleRight sparkle AI GatewayGateway
Search...⌘KFeedback GitHub Vercel LogoSign in with Vercel
An example of how to use the AI Elements to build a workflow visualization.
An example of how to use the AI Elements to build a workflow visualization with interactive nodes and animated connections, built with React Flow .
Preview
Code
Start
Initialize workflow
test
test
Process Data
Transform input
test
test
Decision Point
Route based on conditions
test
test
Success Path
Handle success case
test
test
Error Path
Handle error case
test
test
Complete
Finalize workflow
test
test
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
Let's walk through how to build a workflow visualization using AI Elements. Our example will include custom nodes with headers, content, and footers, along with animated and temporary edge types.
First, set up a new Next.js repo and cd into it by running the following command (make sure you choose to use Tailwind in the project setup):
Terminal
npx create-next-app@latest ai-workflow && cd ai-workflow
Run the following command to install AI Elements. This will also set up shadcn/ui if you haven't already configured it:
Terminal
npx ai-elements@latest
Now, install the required dependencies:
npm
pnpm
yarn
bun
npm i @xyflow/react
We're now ready to start building our workflow!
Let's build the workflow visualization step by step. We'll create the component structure, define our nodes and edges, and configure the canvas.
First, import the necessary AI Elements components in your app/page.tsx:
app/page.tsx
'use client';
import { Canvas } from '@/components/ai-elements/canvas';
import { Connection } from '@/components/ai-elements/connection';
import { Controls } from '@/components/ai-elements/controls';
import { Edge } from '@/components/ai-elements/edge';
import {
Node,
NodeContent,
NodeDescription,
NodeFooter,
NodeHeader,
NodeTitle,
} from '@/components/ai-elements/node';
import { Panel } from '@/components/ai-elements/panel';
import { Toolbar } from '@/components/ai-elements/toolbar';
import { Button } from '@/components/ui/button';
Create a constant object to manage node identifiers. This makes it easier to reference nodes when creating edges:
app/page.tsx
const nodeIds = {
start: 'start',
process1: 'process1',
process2: 'process2',
decision: 'decision',
output1: 'output1',
output2: 'output2',
};
Define the nodes array with position, type, and data for each node in your workflow:
app/page.tsx
const nodes = [\
{\
id: nodeIds.start,\
type: 'workflow',\
position: { x: 0, y: 0 },\
data: {\
label: 'Start',\
description: 'Initialize workflow',\
handles: { target: false, source: true },\
content: 'Triggered by user action at 09:30 AM',\
footer: 'Status: Ready',\
},\
},\
{\
id: nodeIds.process1,\
type: 'workflow',\
position: { x: 500, y: 0 },\
data: {\
label: 'Process Data',\
description: 'Transform input',\
handles: { target: true, source: true },\
content: 'Validating 1,234 records and applying business rules',\
footer: 'Duration: ~2.5s',\
},\
},\
{\
id: nodeIds.decision,\
type: 'workflow',\
position: { x: 1000, y: 0 },\
data: {\
label: 'Decision Point',\
description: 'Route based on conditions',\
handles: { target: true, source: true },\
content: "Evaluating: data.status === 'valid' && data.score > 0.8",\
footer: 'Confidence: 94%',\
},\
},\
{\
id: nodeIds.output1,\
type: 'workflow',\
position: { x: 1500, y: -300 },\
data: {\
label: 'Success Path',\
description: 'Handle success case',\
handles: { target: true, source: true },\
content: '1,156 records passed validation (93.7%)',\
footer: 'Next: Send to production',\
},\
},\
{\
id: nodeIds.output2,\
type: 'workflow',\
position: { x: 1500, y: 300 },\
data: {\
label: 'Error Path',\
description: 'Handle error case',\
handles: { target: true, source: true },\
content: '78 records failed validation (6.3%)',\
footer: 'Next: Queue for review',\
},\
},\
{\
id: nodeIds.process2,\
type: 'workflow',\
position: { x: 2000, y: 0 },\
data: {\
label: 'Complete',\
description: 'Finalize workflow',\
handles: { target: true, source: false },\
content: 'All records processed and routed successfully',\
footer: 'Total time: 4.2s',\
},\
},\
];
Define the connections between nodes. Use animated for active paths and temporary for conditional or error paths:
app/page.tsx
const edges = [\
{\
id: 'edge1',\
source: nodeIds.start,\
target: nodeIds.process1,\
type: 'animated',\
},\
{\
id: 'edge2',\
source: nodeIds.process1,\
target: nodeIds.decision,\
type: 'animated',\
},\
{\
id: 'edge3',\
source: nodeIds.decision,\
target: nodeIds.output1,\
type: 'animated',\
},\
{\
id: 'edge4',\
source: nodeIds.decision,\
target: nodeIds.output2,\
type: 'temporary',\
},\
{\
id: 'edge5',\
source: nodeIds.output1,\
target: nodeIds.process2,\
type: 'animated',\
},\
{\
id: 'edge6',\
source: nodeIds.output2,\
target: nodeIds.process2,\
type: 'temporary',\
},\
];
Define custom node rendering using the compound Node components:
app/page.tsx
const nodeTypes = {
workflow: ({
data,
}: {
data: {
label: string;
description: string;
handles: { target: boolean; source: boolean };
content: string;
footer: string;
};
}) => (
<Node handles={data.handles}>
<NodeHeader>
<NodeTitle>{data.label}</NodeTitle>
<NodeDescription>{data.description}</NodeDescription>
</NodeHeader>
<NodeContent>
<p className="text-sm">{data.content}</p>
</NodeContent>
<NodeFooter>
<p className="text-muted-foreground text-xs">{data.footer}</p>
</NodeFooter>
<Toolbar>
<Button size="sm" variant="ghost">
Edit
</Button>
<Button size="sm" variant="ghost">
Delete
</Button>
</Toolbar>
</Node>
),
};
Map the edge type names to the Edge components:
app/page.tsx
const edgeTypes = {
animated: Edge.Animated,
temporary: Edge.Temporary,
};
Finally, create the main component that renders the Canvas with all nodes, edges, controls, and custom UI panels:
app/page.tsx
const App = () => (
<Canvas
edges={edges}
edgeTypes={edgeTypes}
fitView
nodes={nodes}
nodeTypes={nodeTypes}
connectionLineComponent={Connection}
>
<Controls />
<Panel position="top-left">
<Button size="sm" variant="secondary">
Export
</Button>
</Panel>
</Canvas>
);
export default App;
The workflow visualization demonstrates several powerful features:
NodeHeader, NodeTitle, NodeDescription, NodeContent, NodeFooter) for consistent, structured layouts.Toolbar component attaches contextual actions (like Edit and Delete buttons) to individual nodes, appearing when hovering or selecting them.animated type shows active data flow, while temporary indicates conditional or error paths.Connection component provides styled bezier curves when dragging new connections between nodes.Controls component adds zoom in/out and fit view buttons with a modern, themed design.Panel component allows you to position custom UI elements (like buttons, filters, or legends) anywhere on the canvas.Canvas component auto-fits the view and provides pan/zoom controls out of the box.You now have a working workflow visualization! Feel free to explore dynamic workflows by connecting this to AI-generated process flows, or extend it with interactive editing capabilities using React Flow's built-in features.
v0 clone
An example of how to use the AI Elements to build a v0 clone.
Chain of Thought
A collapsible component that visualizes AI reasoning steps with support for search results, images, and step-by-step progress indicators.
On this page
Tutorial Setup Client Import the components Define node IDs Create mock nodes Create mock edges Create the node types Create the edge types Build the main component Key Features
GitHubEdit this page on GitHub Scroll to topCopy pageOpen in chat