Svelte Component
Experience and ExperienceThumbnail — embed avatars and gallery previews in Svelte.
Install
npm install @liforma/client Experience
Pass experienceId for a self-contained embed. The component handles session mint,
attachment, and cleanup.
<script>
import { Experience } from '@liforma/client/svelte';
<\/script>
<Experience experienceId="exp_T0I7ACMQLBMPG6K" /> If you know the visitor is already registered, pass alreadyConverted with the registration key so conversion rate
excludes them. Prefer setting this on sessionEndpoint mint when you have a
backend.
Host-controlled speech and listening
When your app must call speak(), startListening(), or stopListening() from its own buttons or lesson logic, bind the component with bind:this and type the variable as ExperienceHandle | undefined.
The example uses onStarted to speak after the player unlocks audio, then wires
host Start/Stop buttons to manual listening. See Experience (Svelte) for the full walkthrough.
<script lang="ts">
import {
Experience,
type ExperienceHandle
} from '@liforma/client/svelte';
// Controller from bind:this — undefined until the component mounts.
let experience: ExperienceHandle | undefined = $state();
let audioUnlocked = $state(false);
// Safe point to speak: player start button has unlocked audio.
async function handleStarted() {
audioUnlocked = true;
await experience?.speech.speak({ text: 'Welcome to the lesson.' });
}
// Host-owned Start/Stop — manual speech capture for the learner.
async function startAnswer() {
if (!experience) return;
await experience.startListening();
}
async function finishAnswer() {
if (!experience) return;
const utterance = await experience.stopListening();
console.log(utterance.text);
}
<\/script>
<Experience
bind:this={experience}
experienceId="exp_T0I7ACMQLBMPG6K"
mode="presenter"
speechInputMode="manual"
onStarted={handleStarted}
/>
<button disabled={!audioUnlocked || !experience} onclick={startAnswer}>Start answer</button>
<button disabled={!audioUnlocked || !experience} onclick={finishAnswer}>Stop answer</button> ready() means the Session Launch is resolved and the player is attached. started() means the player-owned user gesture has unlocked audio. Speech and
listening methods do not silently wait for that gesture: they preserve the root API's state
validation and reject if called before started. Use onStarted or await experience.started() before calling them.
Callbacks
Use Svelte 5 callback props for session events. Core callbacks include onReady, onStarted, onUserTranscript, onPlayerStatusChange, onClose, and onError.
<script lang="ts">
import { Experience } from '@liforma/client/svelte';
function reportError(error: Error) {
console.error(error);
}
<\/script>
<Experience
experienceId="exp_T0I7ACMQLBMPG6K"
onReady={({ session }) => console.log('Attached', session.id)}
onStarted={({ mode }) => console.log('Audio unlocked', mode)}
onUserTranscript={(update) => console.log('Transcript', update.text)}
onPlayerStatusChange={(status) => console.log('Player status', status)}
onClose={(event) => console.log('Player closed', event)}
onError={reportError}
/> SvelteKit
For browser embeds, pass experienceId only — let the client mint the session. Do not
load credential-bearing Session Launch payloads in +page.server.ts.
<!-- +page.svelte -->
<Experience experienceId="exp_T0I7ACMQLBMPG6K" /> Props
The component accepts the relevant session launch options and owns restart and cleanup. Changes
to launch-defining props restart the session; callback-only changes do not. Structurally
equivalent startButton objects do not restart it.
Full ExperienceProps, ExperienceHandle, callback, restart, and close
behavior reference: Experience (Svelte).
Close and compatibility
Default close handling navigates to the configured return URL. Supplying onClose overrides automatic navigation. The deprecated LiformaExperience export remains as a
temporary alias; use Experience in new code.
ExperienceThumbnail
<ExperienceThumbnail> renders layered CDN gallery previews (no session mint).
Import from @liforma/client/svelte/thumbnail on gallery / landing pages so the
session SDK stays out of the bundle. Full props and recipes: ExperienceThumbnail.
<script>
import { ExperienceThumbnail } from '@liforma/client/svelte/thumbnail';
<\/script>
<ExperienceThumbnail
experienceId={experience.experienceId}
galleryThumb={experience.galleryThumb}
alt={experience.title}
/>