Getting started
This page builds a video that stops and asks the viewer where to go, then plays the scene they picked:
Building your own player?
This page uses <ivkit-player>, the ready-made player. To draw your own interface instead, go to Custom players with core.
Try it in one HTML file
Save this as index.html. It loads the player from a CDN and uses the example videos of this site, so it works as is:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@ivkit/player@0.2/dist/ivkit-player.min.js"></script>
</head>
<body>
<ivkit-player id="player" controls></ivkit-player>
<script type="module">
const videos = "https://daniel-glz.github.io/ivkit/examples/videos";
const player = document.getElementById("player");
player.story = {
version: "0.1",
start: "intro",
scenes: {
intro: {
src: `${videos}/adventure-intro.mp4`,
events: [
{
type: "question",
id: "path",
at: 4,
text: "Where do you want to go?",
options: [
{ id: "forest", label: "Into the forest", goto: "forest" },
{ id: "city", label: "To the city", goto: "city" },
],
},
],
},
forest: { src: `${videos}/adventure-forest.mp4` },
city: { src: `${videos}/adventure-city.mp4` },
},
};
</script>
</body>
</html>Serve the folder with any local web server, for example npx serve, and open the page. You should see a Play button. At second 4 of intro, the video pauses and the question appears. Each option jumps to its own scene, and when that video ends, the story ends.
How the story works
A story is a plain object:
scenesare the videos, keyed by id, andstartnames the first one.- A scene's
eventsare what happens while it plays. Here, aquestionat second 4 (at). - Each option's
gotonames the scene it branches to.
To use your own videos, replace each src. Writing stories covers the rest: loops, scores, time limits and more.
Install from npm
In a project with a bundler, such as Vite, install the package:
npm install @ivkit/playerpnpm add @ivkit/playeryarn add @ivkit/playerThen import it once, for example in your entry file. Importing it registers the <ivkit-player> element:
import "@ivkit/player";
const player = document.querySelector("ivkit-player")!;
player.story = story;@ivkit/player includes the engine from @ivkit/core. To import from @ivkit/core in your own code, such as the Story type or validateStory, add it too, at the same version.
Until 1.0.0, minor versions may include breaking changes. The ^0.2.0 range that npm saves only accepts 0.2.x updates, and the CDN address above uses @0.2 for the same reason. The changelog lists what changes in each version.
Autoplay
Add the autoplay attribute to start as soon as a story is set. Browsers usually block autoplay with sound, so combine it with muted. If playback is blocked, the player shows the Play button again.
Listening to the viewer
The player fires DOM events whose names start with iv-. Listen to them like any other event, for example to send analytics:
player.addEventListener("iv-answer", (event) => {
const { question, choice } = event.detail;
analytics.track("answer", { question: question.id, choice: choice.id });
});
player.addEventListener("iv-end", (event) => {
console.log("Finished on", event.detail.sceneId);
});In TypeScript, event.detail is typed automatically. See the full list of events.
Using it from a framework
<ivkit-player> is a standard custom element, so it works in any framework. Set story as a property, not an attribute, since it's an object.
import "@ivkit/player";
import { story } from "./story";
export function Player() {
return <ivkit-player controls story={story} />;
}<script setup lang="ts">
import "@ivkit/player";
import { story } from "./story";
</script>
<template>
<ivkit-player controls :story.prop="story" />
</template><script lang="ts">
import "@ivkit/player";
import { story } from "./story";
</script>
<ivkit-player controls {story}></ivkit-player>For React, @ivkit/react Unreleased wraps the element in a component with typed props and event callbacks, and works in React 18 too.
In Vue, tell the compiler that ivkit-player is a custom element, in vite.config.ts:
import vue from "@vitejs/plugin-vue";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [
vue({
template: { compilerOptions: { isCustomElement: (tag) => tag === "ivkit-player" } },
}),
],
});Importing the package is safe during server-side rendering. See Server-side rendering for Next.js, Nuxt, SvelteKit and Astro.
Next steps
- Writing stories: scenes, questions, branching, scores and time limits.
- Hotspots: clickable areas, shapes and animation.
- Styling the player: colors, fonts and
::part(). - Examples: live players with their stories and code.
- Troubleshooting: when something doesn't play or look as expected.