Developer documentation
Framework and deployment examples
Use the same browser loader in custom HTML, JavaScript, React, Next.js and Svelte.
HTML and page builders
Replace EXPERIENCE_ID with your own published UUID in these examples. Use the loader origin from the same environment’s generated snippet.
<div data-rapideye-experience="EXPERIENCE_ID"></div>
<script async src="https://www.rapideye.ai/embed/v1.js"></script> Use a custom HTML feature that permits external scripts and iframes. The required editor permissions depend on your provider and plan; this guide does not assume a provider-specific setting.
If a page builder strips scripts, place the loader in its supported site-code location and retain the experience container in the page. Do not load the same loader origin multiple times intentionally.
<rapideye-experience experience-id='EXPERIENCE_ID'></rapideye-experience>
<script async src='https://www.rapideye.ai/embed/v1.js'></script> The custom element uses the same frame and loader. Configure its experience-id before connecting it; removal performs controller cleanup.
Create one browser loading helper
For the framework examples, create load-rapideye.js in your own project with this helper. This is integration sample code, not a RapidEye package or SDK.
let pending;
let pendingOrigin;
export function loadRapidEye(loaderUrl) {
const expectedOrigin = new URL(loaderUrl, location.href).origin;
if (window.RapidEye?.version === '1') {
return window.RapidEye.origin === expectedOrigin
? Promise.resolve(window.RapidEye)
: Promise.reject(new Error('A different RapidEye origin is already loaded.'));
}
if (pending) {
return pendingOrigin === expectedOrigin
? pending
: Promise.reject(new Error('Load one RapidEye origin per page.'));
}
pendingOrigin = expectedOrigin;
pending = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = loaderUrl;
script.async = true;
script.addEventListener('load', () => {
if (window.RapidEye?.version === '1' && window.RapidEye.origin === expectedOrigin) {
resolve(window.RapidEye);
} else {
pending = undefined;
script.remove();
reject(new Error('The RapidEye loader did not initialize.'));
}
}, { once: true });
script.addEventListener('error', () => {
pending = undefined;
script.remove();
reject(new Error('Could not load RapidEye.'));
}, { once: true });
document.head.appendChild(script);
});
return pending;
} Call it only in the browser. Pass the full loader URL from Copy snippet for your environment. It shares one pending load and refuses a conflicting origin.
Plain JavaScript
Create a container with id player and include this code in your application’s browser module. This programmatic container does not need the auto-mount data attribute.
import { loadRapidEye } from './load-rapideye.js';
const api = await loadRapidEye('https://www.rapideye.ai/embed/v1.js');
const embed = api.mount(document.querySelector('#player'), {
experienceId: 'EXPERIENCE_ID',
});
embed.on('ready', ({ revision }) => console.log('Published revision', revision));
// Before your application removes this instance: embed.destroy(); React and Next.js client components
Mount the browser widget inside an effect and destroy it on cleanup. A cancellation flag prevents a delayed script load from mounting after component removal.
'use client';
import { useEffect, useRef } from 'react';
import { loadRapidEye } from './load-rapideye.js';
export default function RapidEyePlayer({ experienceId }) {
const container = useRef(null);
useEffect(() => {
let removed = false;
let embed;
loadRapidEye('https://www.rapideye.ai/embed/v1.js').then(api => {
if (!removed && container.current) {
embed = api.mount(container.current, { experienceId });
}
}).catch(error => {
if (!removed) console.error('RapidEye could not load', error);
});
return () => {
removed = true;
embed?.destroy();
};
}, [experienceId]);
return <div ref={container} />;
} Pass the published UUID as experienceId. The use client directive supplies the Next.js App Router client boundary; ordinary React applications do not require that directive.
Svelte browser lifecycle
This Svelte 4-style component loads on mount and returns synchronous cleanup. Keep the async work inside the callback rather than returning an async cleanup function.
<script>
import { onMount } from 'svelte';
import { loadRapidEye } from './load-rapideye.js';
export let experienceId;
let container;
onMount(() => {
let removed = false;
let embed;
loadRapidEye('https://www.rapideye.ai/embed/v1.js').then(api => {
if (!removed) embed = api.mount(container, { experienceId });
}).catch(error => {
if (!removed) console.error('RapidEye could not load', error);
});
return () => {
removed = true;
embed?.destroy();
};
});
</script>
<div bind:this={container}></div> Pass the published UUID as experienceId. This example mounts that prop once; recreate the component or explicitly destroy/remount when switching experiences.
Local, preview and production
- Copy a snippet from the RapidEye environment you intend to test.
- Add the exact local hostname and port for local HTTP testing.
- Add each intended HTTPS preview or production hostname before publication.
- Use a fresh viewer session and validate the actual page policies.
- Keep development and production loader origins separate.
A direct runtime iframe bypasses the wrapper’s private-grant handshake, resizing and controller API. Use the documented loader or custom element instead of copying a raw runtime URL.
No dedicated embed hostname is required by the current deployment. Use the generated origin; custom hostname provisioning is an operator concern, not a partner script option.