Skip to content

Framework Integration

FlowDrop is built with Svelte 5, but can be mounted into any framework via the mount API.

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}
eventHandlers={{
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}

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();

See Mount API for the complete options and return value.

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.

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.

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
}
}
}
});

For the complete event reference, see Event System.

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: no editing at all
const app = await mountFlowDropApp(container, {
readOnly: true
});
// Locked: can view and configure nodes, but not add/remove/connect
const app = await mountFlowDropApp(container, {
lockWorkflow: true
});