Widget Loader
Dynamic async widget component loader with code-splitting, error boundaries, and Valibot validation.
On this page
The Widget Loader enables dynamic, asynchronous loading of widget components with code-splitting. Widgets are loaded on-demand rather than bundled upfront, improving initial bundle size and time-to-interactive.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
loader |
() => Promise<{ default: any }> |
required | Dynamic import function for the widget component |
field |
FieldInstance |
required | Field configuration from the collection schema |
value |
any |
— | Current field value for binding |
tenantId |
string \| null |
— | Multi-tenant isolation scope |
collectionName |
string |
— | Parent collection name for context |
WidgetData |
Record<string, any> |
{} |
Additional widget configuration data |
onFieldSync |
() => void |
— | Callback fired on value change — patches parent store field-by-field (avoids full-form JSON.stringify) |
Features
- Code-Splitting: Widget components imported via dynamic
loader()function, enabling per-widget lazy loading - Valibot Runtime Validation: When a widget defines a
validationSchema, values are validated at runtime withsafeParse() - Error Boundary: Catches widget load failures and renders a fallback UI with retry capability
- Field-Store Sync: The
onFieldSynccallback lets parent components patch individual fields without serializing the entire form - Svelte 5 Runes: Uses
$state(),$derived(), and$effect()for reactive updates
Usage
<WidgetLoader
loader={() => import("./widgets/my-widget/input.svelte")}
{field}
bind:value={entryValue}
tenantId={locals.tenantId}
/>
Related
Was this page helpful?