Quick Start
Basic setup
Import Scena
Import the factory function and the required stylesheet:
import { useScena } from '@retoo/scena';
import '@retoo/scena/styles';
Create a factory
useScena() returns a factory object that manages widget instances. One factory can create multiple independent widgets:
const scena = useScena();
Mount the widget
Pass a config object to mount(). The only required field is video.src — all other options use defaults:
const instance = await scena.mount({
video: { src: '/video.mp4' }
});
mount() is async — it resolves after the widget is rendered and attached to the DOM. By default, the widget appears in the bottom-right corner of the viewport.
Full example
A complete setup with a custom shape, poster image, and CTA button:
import {
useScena,
ComponentSize,
ComponentShape,
ComponentPosition,
} from '@retoo/scena';
import '@retoo/scena/styles';
const scena = useScena();
const instance = await scena.mount({
video: {
src: '/video.mp4',
poster: '/poster.jpg',
autoplay: false,
loop: true,
muted: true,
},
size: ComponentSize.MD,
shape: ComponentShape.CIRCLE,
container: { position: ComponentPosition.RELATIVE },
ctaButton: { text: 'Get in touch' },
});
Controlling playback
The instance.api.controller interface provides full control over the video element. All methods are available immediately after mount:
// Play and pause
await instance.api.controller.play();
instance.api.controller.pause();
// Seek to a specific time in seconds
instance.api.controller.seek(15);
// Volume control (0.0 to 1.0)
instance.api.controller.setVolume(0.5);
instance.api.controller.mute();
instance.api.controller.unmute();
You can also read the current playback state at any time:
instance.api.controller.currentTime;
instance.api.controller.duration;
instance.api.controller.progress;
instance.api.controller.isMuted;
instance.api.controller.state;
Listening to events
Subscribe to typed events through instance.api.events to connect the widget with your application logic:
import { ScenaEvent } from '@retoo/scena';
// User clicked the CTA button
instance.api.events.on(ScenaEvent.ON_CTA_CLICK, () => {
window.location.href = '/contact';
});
// Video finished playing
instance.api.events.on(ScenaEvent.ON_VIDEO_ENDED, () => {
showNextStep();
});
// Track playback progress
instance.api.events.on(ScenaEvent.ON_VIDEO_TIME_UPDATE, ({ state }) => {
analytics.track('video_progress', { time: state.currentTime });
});
To remove a specific handler, pass the same function reference to off():
const handler = () => console.log('played');
instance.api.events.on(ScenaEvent.ON_VIDEO_PLAY, handler);
// Later
instance.api.events.off(ScenaEvent.ON_VIDEO_PLAY, handler);
Runtime
Modify any config property after mount without recreating the widget. mergeConfig() performs a deep merge — only the fields you pass are updated:
import { ComponentSize, ComponentShape } from '@retoo/scena';
// Change size and shape
instance.config.mergeConfig({
size: ComponentSize.LG,
shape: ComponentShape.PORTRAIT,
});
// Update CTA button text
instance.config.mergeConfig({ ctaButton: { text: 'Buy now' } });
// Disable a component entirely
instance.config.mergeConfig({ ctaButton: false });
To replace the entire config at once, use setConfig():
import { ComponentSize, ComponentShape } from '@retoo/scena';
instance.config.setConfig({
video: { src: '/video.mp4' },
size: ComponentSize.SM,
shape: ComponentShape.SQUARE,
});