Framework integration
Use FlowDrop with Svelte, vanilla JS, React, Vue, Angular, or any framework.
FlowDrop is built with Svelte 5, but can be mounted into any framework via the mount API.
Svelte (Native)
Use FlowDrop components directly in Svelte:
<script>
import { App } from '@flowdrop/flowdrop/editor';
import { createEndpointConfig } from '@flowdrop/flowdrop/core';
import '@flowdrop/flowdrop/styles';
const endpointConfig = createEndpointConfig('/api/flowdrop');
</script>
<App
{endpointConfig}
showNavbar={true}
onAfterSave={async (workflow) => console.log('Saved:', workflow.id)}
/>For SvelteKit, ensure FlowDrop runs only on the client:
<script>
import { browser } from '$app/environment';
import { App } from '@flowdrop/flowdrop/editor';
</script>
{#if browser}
<App {endpointConfig} />
{/if}Vanilla JS / React / Vue / Angular
Use the mount API to embed FlowDrop in any container element:
import { mountFlowDropApp } from '@flowdrop/flowdrop/editor';
import { createEndpointConfig } from '@flowdrop/flowdrop/core';
import '@flowdrop/flowdrop/styles';
const app = await mountFlowDropApp(document.getElementById('editor'), {
endpointConfig: createEndpointConfig('/api/flowdrop'),
eventHandlers: {
onDirtyStateChange: (isDirty) => console.log('Unsaved:', isDirty),
onAfterSave: async (workflow) => console.log('Saved!', workflow)
}
});
// Programmatic control
app.save();
app.getWorkflow();
app.isDirty();
app.destroy();The returned handle also exposes app.export() and the mount's state container at
app.instance. For programmatic state changes, reach through the instance —
app.instance.workflow.actions.*, app.instance.history.undo(), and so on.
See Mount API for the complete options and return value.
API Configuration
Connect to your backend by configuring endpoints:
import { createEndpointConfig } from '@flowdrop/flowdrop/core';
// Simple: just a base URL (all endpoints use defaults)
const config = createEndpointConfig('/api/flowdrop');
// Custom: override specific endpoint paths
const config = createEndpointConfig({
baseUrl: 'https://api.example.com',
endpoints: {
nodes: { list: '/nodes', get: '/nodes/{id}' },
workflows: {
list: '/workflows',
get: '/workflows/{id}',
create: '/workflows',
update: '/workflows/{id}'
}
}
});See Backend Implementation for which endpoints to implement.
Authentication
FlowDrop supports three auth providers. Quick examples:
import { NoAuthProvider, StaticAuthProvider, CallbackAuthProvider } from '@flowdrop/flowdrop/core';
// No auth (development)
authProvider: new NoAuthProvider();
// Static bearer token
authProvider: new StaticAuthProvider({ type: 'bearer', token: 'your-jwt' });
// Dynamic token with refresh (enterprise)
authProvider: new CallbackAuthProvider({
getToken: async () => authService.getAccessToken(),
onUnauthorized: async () => authService.refreshToken()
});For full details on each provider, token refresh patterns, and OAuth2 integration, see Authentication Patterns.
Event Handlers
React to all 11 editor lifecycle events:
const app = await mountFlowDropApp(container, {
eventHandlers: {
onWorkflowChange: (workflow, changeType) => {
analytics.track('workflow_modified', { changeType });
},
onDirtyStateChange: (isDirty) => {
saveButton.disabled = !isDirty;
},
onBeforeSave: async (workflow) => {
// Return false to cancel save
},
onAfterSave: async (workflow) => {
showNotification('Saved!');
},
onApiError: (error, operation) => {
if (error.message.includes('401')) {
redirectToLogin();
return true; // suppress default toast
}
}
}
});The mount options bag groups handlers under eventHandlers. The <App>
component instead takes the same handlers as flat on* props (onAfterSave,
onApiError, …).
For the complete event reference, see Event System.
Feature Flags
Enable optional editor features:
const app = await mountFlowDropApp(container, {
features: {
autoSaveDraft: true, // default: true
autoSaveDraftInterval: 30000, // default: 30 seconds
showToasts: true // default: true
}
});Read-Only & Lock Modes
The mode option controls canvas editing. 'readonly' and 'locked' both
disable node dragging, connecting, selecting, proximity-connect, and node swap.
// Read-only: no canvas editing
const app = await mountFlowDropApp(container, {
mode: 'readonly'
});
// Locked: same disabled interactions, distinct intent
const app = await mountFlowDropApp(container, {
mode: 'locked'
});Next Steps
- Mount API — complete mount options and return values
- Backend Implementation — build the API
- Authentication Patterns — secure your integration
- Deployment — production deployment patterns
- Event System — all 11 event handlers