ExperienceThumbnail

Layered CDN gallery previews with optional parallax and hosted-player launch — available in Svelte, React, Next.js, and vanilla.

Overview

<ExperienceThumbnail> renders the same layered Meet-style preview used on www.liforma.ai: avatar plate plus optional location background and foreground, with lazy load and pointer/scroll parallax. It is a catalog preview, not a live player.

Painting the thumb needs no API key and no origin allowlist — pass CDN URLs from your server-side catalog fetch. Keys and allowlists apply only when a session starts (hosted launch click, or a page that mounts <Experience>).

Install

npm install @liforma/client
SurfaceImport / tag
Svelte@liforma/client/svelte
React@liforma/client/react
Next.js@liforma/client/next (client component)
Vanilla<liforma-experience-thumbnail> via the CDN v2 script

Zero-config hosted launch

Pass experienceId and galleryThumb with no href / onclick. Click opens player.liforma.ai/{experienceId}?returnUrl=… and returns to the embedding page on close. Add your site origin to the project allowlist first (launch path only).

Card.svelte
<script>
  import { ExperienceThumbnail } from '@liforma/client/svelte';
<\/script>

<ExperienceThumbnail
  experienceId={experience.experienceId}
  galleryThumb={experience.galleryThumb}
  alt={experience.title}
/>
GalleryCard.tsx
import { ExperienceThumbnail } from '@liforma/client/react';
// Next.js App Router client files can also use:
// import { ExperienceThumbnail } from '@liforma/client/next';

export function GalleryCard({ experience }) {
  return (
    <ExperienceThumbnail
      experienceId={experience.experienceId}
      galleryThumb={experience.galleryThumb}
      alt={experience.title}
    />
  );
}
index.html
<script type="module" src="https://cdn.liforma.ai/sdk/v2/client.js"><\/script>

<liforma-experience-thumbnail
  experience-id="exp_01EXAMPLES_COFFEE_BARISTA"
  alt="Spanish Cafe"
  gallery-thumb='{"avatarImage":"https://cdn.liforma.ai/avatars/05a87620/256/05a87620_neutral.webp"}'
></liforma-experience-thumbnail>

App-owned routing

When your app owns the session page (Meet-style), pass href to your slug route. That page should mount <Experience> with experienceId (and usually sessionEndpoint for authenticated mint).

Card.svelte
<script>
  import { ExperienceThumbnail } from '@liforma/client/svelte';
<\/script>

<ExperienceThumbnail
  galleryThumb={experience.galleryThumb}
  alt={experience.title}
  href={`/experiences/${experience.slug}`}
/>

Presentational (parent owns the link)

Omit experienceId, href, and onclick. Wrap the thumb yourself and use alt="" when the parent already provides the accessible name.

<a href="/experiences/{experience.slug}" aria-label={experience.title}>
  <ExperienceThumbnail galleryThumb={experience.galleryThumb} alt="" />
</a>

Click behaviour

ProvideClick does
experienceId (no href/onclick)Open hosted player; return to this page
hrefNavigate to that URL
onclick / onClickRun your handler (modal, analytics, SPA goto)
None of the aboveNon-interactive preview

Priority: href > click-only > hosted default > presentational.

Hosted launch is for public experiences. Authenticated gallery cards should use href / onclick plus your BFF session route — not the hosted player default.

Props

PropTypeNotes
galleryThumbGalleryThumbCatalog shape: avatarImage, optional backgroundImage / foregroundImage
avatarImagestringFlattened alternative to galleryThumb
altstringAccessible name (use "" when a parent link names the card)
experienceIdstringRequired for hosted-player default
hrefstringApp-owned destination; disables hosted default
onclick / onClick(event) => voidCustom handler; may preventDefault with href
returnUrlstringHosted close destination; default = current page URL
parallaxbooleanDefault true; respects prefers-reduced-motion
lazybooleanDefault true; IntersectionObserver load
fallbackImagestringFlat image if the layered avatar fails

Layout and image size

The component fills its container. Set width / aspect-ratio on the parent — there is no size prop. CDN assets are thumb-tier only:

  • Avatars: /256/ (larger tiers are rewritten automatically)
  • Locations: 256x256

Prefer catalog galleryThumb over flat thumbnailPath (which may still point at larger plates).

Gallery walkthrough

For a full SvelteKit catalog → cards → slug → <Experience> flow, see Dynamic Experience Gallery.