FlowProvider
Configure global defaults for all flows in your application. Provides shared persistence, callbacks, and configuration.
Import
Section titled “Import”import { FlowProvider } from "@useflow/react";Basic usage
Section titled “Basic usage”import { FlowProvider, createLocalStorageStore, createPersister } from "@useflow/react";
const globalPersister = createPersister({ store: createLocalStorageStore()});
function App() { return ( <FlowProvider persister={globalPersister} saveMode="navigation" saveDebounce={500} > <YourApp /> </FlowProvider> );}Configuration props
Section titled “Configuration props”| Prop | Type | Default | Description |
|---|---|---|---|
persister | FlowPersister | - | Default persister for all flows |
saveMode | "always" | "navigation" | "manual" | "navigation" | When to auto-save |
saveDebounce | number | 300 | Debounce delay in ms |
onPersistenceError | (error: Error) => void | - | Global error handler |
Global callbacks
Section titled “Global callbacks”| Callback | Type | Description |
|---|---|---|
onFlowStart | (event) => void | When any flow starts |
onFlowComplete | (event) => void | When any flow completes |
onStepTransition | (event) => void | When any step changes |
Examples
Section titled “Examples”Global persistence
Section titled “Global persistence”All flows will use this persister by default:
const persister = createPersister({ store: createLocalStorageStore(), ttl: 7 * 24 * 60 * 60 * 1000 // 7 days});
<FlowProvider persister={persister}> {/* All flows inherit this persister */} <Flow flow={onboardingFlow}> {/* Uses global persister */} </Flow>
<Flow flow={checkoutFlow} persister={customPersister}> {/* Override with custom persister */} </Flow></FlowProvider>Global analytics
Section titled “Global analytics”Track all flow events in one place:
<FlowProvider onFlowStart={({ flowId, variantId, context }) => { analytics.track('flow_started', { flow_id: flowId, variant: variantId, initial_context: context }); }}
onStepTransition={({ flowId, from, to, direction }) => { analytics.track('step_changed', { flow_id: flowId, from_step: from, to_step: to, direction }); }}
onFlowComplete={({ flowId, context }) => { analytics.track('flow_completed', { flow_id: flowId, final_context: context }); }}> <YourApp /></FlowProvider>Error handling
Section titled “Error handling”Centralized error handling for all flows:
<FlowProvider onPersistenceError={(error) => { // Log to error service errorReporter.log(error);
// Show user notification if (error.name === 'QuotaExceededError') { toast.error('Storage full - some progress may not be saved'); } }}> <YourApp /></FlowProvider>Save configuration
Section titled “Save configuration”Configure save behavior globally:
<FlowProvider saveMode="always" // Save on every change saveDebounce={1000} // Wait 1 second before saving> {/* All flows use these settings */} <Flow flow={surveyFlow}> {/* Saves automatically on every change */} </Flow>
<Flow flow={checkoutFlow} saveMode="manual"> {/* Override to manual saving */} </Flow></FlowProvider>Access provider config
Section titled “Access provider config”Use the useFlowConfig hook to access provider configuration:
import { useFlowConfig } from "@useflow/react";
function MyComponent() { const config = useFlowConfig();
return ( <div> Save mode: {config?.saveMode || 'navigation'} Has persister: {config?.persister ? 'Yes' : 'No'} </div> );}Event types
Section titled “Event types”onFlowStart
Section titled “onFlowStart”type FlowStartEvent = { flowId: string; variantId?: string; instanceId?: string; context: FlowContext;}onStepTransition
Section titled “onStepTransition”type StepTransitionEvent = { flowId: string; variantId?: string; instanceId?: string; from: string; to: string; direction: "forward" | "backward"; oldContext: FlowContext; newContext: FlowContext;}onFlowComplete
Section titled “onFlowComplete”type FlowCompleteEvent = { flowId: string; variantId?: string; instanceId?: string; context: FlowContext;}Advanced patterns
Section titled “Advanced patterns”Environment-based configuration
Section titled “Environment-based configuration”const isDevelopment = process.env.NODE_ENV === 'development';
<FlowProvider persister={isDevelopment ? undefined : persister} saveMode={isDevelopment ? "manual" : "navigation"} onStepTransition={isDevelopment ? console.log : undefined}> <App /></FlowProvider>Multi-provider setup
Section titled “Multi-provider setup”Different configs for different parts of your app:
function App() { return ( <> {/* Onboarding flows with long TTL */} <FlowProvider persister={onboardingPersister}> <OnboardingSection /> </FlowProvider>
{/* Checkout flows with short TTL */} <FlowProvider persister={checkoutPersister}> <CheckoutSection /> </FlowProvider> </> );}Dynamic configuration
Section titled “Dynamic configuration”Update provider config based on user preferences:
function App() { const [saveEnabled, setSaveEnabled] = useState(true);
return ( <FlowProvider persister={saveEnabled ? persister : undefined} saveMode={saveEnabled ? "navigation" : "manual"} > <Settings onToggleSave={setSaveEnabled} /> <YourFlows /> </FlowProvider> );}Best practices
Section titled “Best practices”Don’t over-configure
Section titled “Don’t over-configure”// ❌ Too much in provider<FlowProvider persister={persister} saveMode="always" saveDebounce={100} onFlowStart={...} onStepTransition={...} onFlowComplete={...} onPersistenceError={...}>
// ✅ Only shared config<FlowProvider persister={persister} onPersistenceError={handleError}>Flow-specific overrides
Section titled “Flow-specific overrides”<FlowProvider persister={defaultPersister}> {/* Uses default */} <Flow flow={flow1} />
{/* Override for specific flow */} <Flow flow={flow2} persister={customPersister} saveMode="always" /></FlowProvider>Testing with provider
Section titled “Testing with provider”import { FlowProvider, createMemoryStore } from "@useflow/react";
const testPersister = createPersister({ store: createMemoryStore()});
function renderWithProvider(ui: ReactElement) { return render( <FlowProvider persister={testPersister}> {ui} </FlowProvider> );}
test('flow completes', () => { renderWithProvider(<MyFlow />); // Test with persistence enabled});TypeScript
Section titled “TypeScript”The provider is fully typed:
import { FlowProvider, FlowProviderProps } from "@useflow/react";
const config: FlowProviderProps = { persister: myPersister, saveMode: "navigation", callbacks: { onFlowStart: ({ flowId }) => console.log(flowId) }};
<FlowProvider {...config}> <App /></FlowProvider>Related
Section titled “Related”- createPersister() - Create persisters
- Flow Component - Individual flow config
- Global Configuration Guide - Patterns and examples