FlowDrop Docs

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

On this page