@presage-kit/svelte
Svelte bindings for Presage. Provides context helpers and reactive stores for adaptive UIs in Svelte 4 and 5.
pnpm add @presage-kit/core @presage-kit/sveltesetAdaptiveClient(client)
Section titled “setAdaptiveClient(client)”Sets the AdaptiveClient in Svelte’s context. Must be called in a root component (e.g. +layout.svelte).
<script> import { setAdaptiveClient } from '@presage-kit/svelte' import { createAdaptiveClient } from '@presage-kit/core'
const client = createAdaptiveClient({ /* ... */ }) setAdaptiveClient(client)</script>
<slot />Parameters:
| Param | Type | Required | Description |
|---|---|---|---|
client | AdaptiveClient | Yes | Client from createAdaptiveClient() |
Implementation: Calls Svelte’s setContext() with a symbol key, making the client available to all descendant components.
getAdaptiveClient()
Section titled “getAdaptiveClient()”Returns the AdaptiveClient from Svelte’s context.
import { getAdaptiveClient } from '@presage-kit/svelte'
const client = getAdaptiveClient()
client.track('feature_used', { featureId: 'export' })client.identify('user-789', { role: 'admin' })const context = client.getContext()Return type: AdaptiveClient
Throws: Error if setAdaptiveClient() has not been called in a parent component.
useAdaptive(adaptationId, config)
Section titled “useAdaptive(adaptationId, config)”Resolves an adaptation point reactively. Returns Svelte Readable stores that update when user context changes.
import { useAdaptive } from '@presage-kit/svelte'
const { selectedVariant, resolution, context, track } = useAdaptive('onboarding', { variants: ['guided-tour', 'standard', 'minimal'] as const, defaultVariant: 'standard',})Parameters:
| Param | Type | Description |
|---|---|---|
adaptationId | string | Unique adaptation point ID |
config.variants | readonly V[] | Array of variant IDs |
config.defaultVariant | NoInfer<V> | Default variant (must be in variants) |
config.strategy | Strategy | Optional. Defaults to { type: 'rules' } |
Return type:
| Field | Type | Description |
|---|---|---|
selectedVariant | Readable<V> | Currently selected variant |
resolution | Readable<ResolvedAdaptation> | Full resolution metadata |
context | Readable<UserContext> | Current user context |
track | (event: string, props?: Record<string, unknown>) => void | Scoped track function |
Reactivity: Uses derived() stores internally. When the client state changes, all stores update automatically. Use the $ prefix in templates to subscribe.
Impressions: Tracks presage:impression events automatically when the selected variant changes, using a derived() store that fires on each change.
Usage in templates:
<script lang="ts"> import { useAdaptive } from '@presage-kit/svelte'
const { selectedVariant } = useAdaptive('panel', { variants: ['compact', 'expanded'] as const, defaultVariant: 'compact', })</script>
{#if $selectedVariant === 'compact'} <CompactPanel />{:else} <ExpandedPanel />{/if}useVariant(adaptationId, config)
Section titled “useVariant(adaptationId, config)”Lightweight function returning only the selected variant as a readable store.
import { useVariant } from '@presage-kit/svelte'
const variant = useVariant('layout', { variants: ['sidebar', 'topnav'] as const, defaultVariant: 'sidebar',})Parameters: Same as useAdaptive().
Return type: Readable<V> — A store containing the selected variant string.
Internally delegates to useAdaptive() and returns selectedVariant.
Usage in templates:
<script lang="ts"> import { useVariant } from '@presage-kit/svelte'
const variant = useVariant('cta-style', { variants: ['primary', 'secondary'] as const, defaultVariant: 'primary', })</script>
<button class="btn btn--{$variant}">Get Started</button>Differences from React and Vue Adapters
Section titled “Differences from React and Vue Adapters”| Feature | React | Vue | Svelte |
|---|---|---|---|
| Provider | <AdaptiveProvider> | AdaptivePlugin | setAdaptiveClient() |
| Declarative component | <Adaptive> + <Variant> | Not included | Not included |
| Adaptive navigation | <AdaptiveNav> | Manual | Manual |
| Return type | Plain object | Reactive getters | Readable stores |
| State bridge | useSyncExternalStore | ref + listen() | readable() + listen() |
| Subscribe syntax | Direct access | Direct access | $store prefix |
The Svelte adapter is intentionally lean. Svelte’s {#if} blocks and store subscriptions make it natural to conditionally render variants without wrapper components.