Quick Start Guide
This guide walks you through integrating <oim-player> into your web applications, from plain HTML to modern frontend frameworks.
1. Quickest Path: Plain HTML & CDN
The fastest way to embed interactive .oim files is using our pre-compiled Web Component script loaded directly via CDN:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OIM Interactive Media</title>
<!-- Load the OIM Player Web Component -->
<script src="https://cdn.oim.media/player/v1/oim-player.js"></script>
</head>
<body>
<!-- Embed interactive image (a signed demo in Spanish and English) -->
<oim-player
src="https://cdn.oim.media/demo/imagen-muestra.oim.png"
lang="en"
mode="full"
fit="contain"
style="max-width: 800px; height: 600px; display: block; margin: 0 auto;">
</oim-player>
</body>
</html>Stable URL and caching
/player/v1/ is the stable path: it stays compatible for as long as the major version is 1. Browsers cache the script for up to 4 hours, so an update can take that long to reach a returning visitor.
Opening the .oim.png file directly vs. using <oim-player>
An .oim file is a valid standard PNG image where the base visual background is stored in Layer −1 (Baked Image) and all interactive typography, buttons, and multilingual texts are stored in the Layer +1 (Dynamic) metadata chunk.
- If you open
https://cdn.oim.media/demo/imagen-muestra.oim.pngdirectly in your browser's address bar (or with<img>), the browser's default image viewer only renders the static background image without text. - To decode and render the dynamic text, multilingual switching, and animations, the file must be embedded using
<oim-player>(as shown in the code snippet above).
Where to host your .oim
The player downloads the file with fetch, so the server must allow your page's origin (CORS). The demo above is served from cdn.oim.media, which allows any origin.
Cloud Hosting & CDN Embeds
When hosted at an authorized embed endpoint (e.g. https://embed.oim.media/<id>.oim.png), the file is served from global edge caches with permissive CORS headers, providing embed-ready code for any website.
Self-hosting the player
If you copy oim-player.js to your own server, copy the vendor/ folder next to it as well. The player fetches Lottie from there only when a .oim contains a Lottie layer.
2. Modern Package Installation
If you are using a bundler (Vite, Webpack, Rollup) or a component framework, install @oim-media/player-oim:
Package Availability
@oim-media/player-oim is available through the private workspace and npm registry. Always use pnpm within the OIM ecosystem repository.
# Using pnpm (recommended)
pnpm add @oim-media/player-oim
# Or using npm
npm install @oim-media/player-oimIn your main entry file (e.g. main.ts or index.js), import the package to register the custom element:
import '@oim-media/player-oim';
// The <oim-player> element is now registered in window.customElements3. Production Framework Integrations
Vanilla TypeScript / JavaScript
import '@oim-media/player-oim';
const player = document.querySelector('oim-player') as any;
// Listen for metadata loading and signature verification
player.addEventListener('oim:loaded', (event: CustomEvent) => {
const { metadata, security } = event.detail;
console.log(`Document loaded. Security status: ${security}`);
console.log(`Available languages:`, player.languages);
});
// Intercept interactive user actions
player.addEventListener('oim:action', (event: CustomEvent) => {
console.log(`User interacted with slot: ${event.detail.slot}`);
// Custom business logic: prevent default internal state change if needed
if (event.detail.slot === 'purchase_btn') {
event.preventDefault(); // Vetoes internal DOM state mutation
openCheckoutModal();
}
});
// Imperative language switching
function switchLanguage(code: string) {
player.setLang(code);
}React 18 / 19 & Next.js
Because Custom Elements accept attributes as strings and dispatch custom DOM events, wrap <oim-player> with a typed React component:
import React, { useEffect, useRef } from 'react';
import '@oim-media/player-oim';
// Extend JSX IntrinsicElements for TypeScript
declare global {
namespace JSX {
interface IntrinsicElements {
'oim-player': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
src?: string;
lang?: string;
mode?: 'full' | 'image';
fit?: 'contain' | 'cover';
align?: 'center' | 'top' | 'bottom';
'allow-dynamic-colors'?: 'true' | 'false';
'activate-on'?: 'visible' | 'hover' | 'manual';
};
}
}
}
interface OimViewerProps {
src: string;
lang?: string;
onAction?: (slotId: string, targets: string[]) => void;
}
export function OimViewer({ src, lang = 'en', onAction }: OimViewerProps) {
const playerRef = useRef<HTMLElement>(null);
useEffect(() => {
const el = playerRef.current;
if (!el) return;
const handleAction = (e: any) => {
onAction?.(e.detail.slot, e.detail.targets);
};
el.addEventListener('oim:action', handleAction);
return () => el.removeEventListener('oim:action', handleAction);
}, [onAction]);
return (
<div style={{ width: '100%', height: '500px' }}>
<oim-player
ref={playerRef}
src={src}
lang={lang}
mode="full"
fit="contain"
/>
</div>
);
}Vue 3
In your vite.config.ts, inform Vue that <oim-player> is a native custom element:
// vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('oim-') || tag.startsWith('ovm-'),
},
},
}),
],
});Then use it seamlessly in single-file components:
<script setup lang="ts">
import { ref } from 'vue';
import '@oim-media/player-oim';
const currentLang = ref('en');
function onOimAction(event: any) {
console.log('Action triggered:', event.detail.slot);
}
</script>
<template>
<div class="player-container">
<div class="controls">
<button @click="currentLang = 'en'">English</button>
<button @click="currentLang = 'es'">Español</button>
</div>
<oim-player
:src="'/media/sample.oim.png'"
:lang="currentLang"
mode="full"
@oim:action="onOimAction"
/>
</div>
</template>4. Key Attributes Reference
| Attribute | Type | Default | Description |
|---|---|---|---|
src | string | "" | URL to .oim.png or assigned Blob. |
lang | string | "en" | Active language code to resolve in slot.content. |
mode | "full" | "image" | "image" | "full" activates WAAPI animations and interactive click/hover states. "image" preserves static fidelity. |
fit | "contain" | "cover" | "contain" | How the baked base image (Layer −1) fits inside the player container. |
align | "center" | "top" | "bottom" | "center" | Alignment of the artwork inside the container box. |
activate-on | "visible" | "hover" | "manual" | "visible" | Whether animations play when scrolled into view, only on pointer hover (hover), or only when the page calls play() (manual). |
allow-dynamic-colors | "true" | "false" | "true" | When "true", resolves --oim-color-* CSS variables. |