Image Assets
Elucim supports two ways to work with images:
- Direct URLs — set
srcto a URL or data URI (simple, no setup) - Asset references — store an opaque
refin the document, resolved to a URL at render time (flexible, app-integrated)
Asset references let you integrate Elucim with your app’s asset library, CMS, or API without baking URLs into the document.
How it works
Section titled “How it works”The system has three pieces:
| Piece | Package | Purpose |
|---|---|---|
ImageResolverProvider | @elucim/core | React context that resolves ref → URL |
onBrowseImage | @elucim/editor | Callback for the editor’s image picker UI |
BrowseImageResult | @elucim/editor | What the picker returns (ref, displayName, src, dimensions) |
Resolution rules
Section titled “Resolution rules”When an <Image> element has an imageRef prop:
- If a resolver is provided → call
resolver(ref)to get the URL - If no resolver → fall back to
src - If no
imageRef→ usesrcdirectly
Editor integration
Section titled “Editor integration”Image picker
Section titled “Image picker”Provide onBrowseImage to let users pick images from your app’s asset library:
import { ElucimEditor, type BrowseImageResult } from '@elucim/editor';
async function handleBrowseImage(): Promise<BrowseImageResult | null> { // Open your app's asset picker (modal, dialog, etc.) const asset = await myAssetPicker.open(); if (!asset) return null; // user cancelled
return { ref: asset.id, // opaque ID stored in the document displayName: asset.name, // shown in the inspector src: asset.thumbnailUrl, // optional fallback URL width: asset.width, // optional — auto-sizes the element height: asset.height, };}
<ElucimEditor onBrowseImage={handleBrowseImage} />When onBrowseImage is set, the inspector shows a ”…” browse button next to image fields. When a ref is set, the inspector shows the asset name instead of the URL field.
Image resolver
Section titled “Image resolver”Provide imageResolver so ref-based images render correctly in the editor preview:
<ElucimEditor onBrowseImage={handleBrowseImage} imageResolver={(ref) => `https://cdn.example.com/assets/${ref}`}/>Player / viewer integration
Section titled “Player / viewer integration”The player needs the same resolver to render ref-based images:
import { DslRenderer, type ImageResolverFn } from '@elucim/dsl';
const resolver: ImageResolverFn = (ref) => `https://cdn.example.com/assets/${ref}`;
<DslRenderer dsl={document} imageResolver={resolver}/>Or wrap any component tree with the provider directly:
import { ImageResolverProvider } from '@elucim/core';
<ImageResolverProvider resolver={resolver}> <Player width={800} height={600} fps={30} durationInFrames={120}> {/* Images with imageRef will be resolved */} </Player></ImageResolverProvider>Async resolvers
Section titled “Async resolvers”Resolvers can return a Promise<string> for signed URLs or token-gated assets:
const resolver: ImageResolverFn = async (ref) => { const res = await fetch(`/api/assets/${ref}/url`); return res.text();};During async resolution, the image falls back to src (if provided) until the resolved URL is ready.
DSL schema
Section titled “DSL schema”In the JSON DSL, images can include ref and displayName:
{ "type": "image", "ref": "asset-abc-123", "displayName": "Hero Banner", "src": "https://example.com/fallback.png", "x": 0, "y": 0, "width": 800, "height": 450}Either src or ref (or both) must be present. The validator rejects images with neither.
Type reference
Section titled “Type reference”// The resolver function — sync or asynctype ImageResolverFn = (ref: string) => string | Promise<string>;
// What the image picker returnsinterface BrowseImageResult { src?: string; // URL or data URI ref?: string; // opaque asset reference displayName?: string; // human-readable label width?: number; // natural width in pixels height?: number; // natural height in pixels}
// The picker callbacktype BrowseImageFn = () => Promise<BrowseImageResult | null>;