Embedding the player page
The player page served from a domain of its own and framed by your site. The player runs on its own origin, so a hostile
archive reaches the player’s data and not the embedding site’s, and storage is
partitioned per embedding site. The embedding page hears what it asks for: the frame’s
height always, and the xAPI statements when the address names the page’s own origin.
The address also takes the element’s display options: this example asks for H5P’s
action bar with the download and rights-of-use buttons.
In production, npx @missing-elements/h5p-embed writes this page as a static
site for a domain your organisation runs.
Markup
HTML
<!-- This site's copy of the page. Your own player domain, from npx @missing-elements/h5p-embed,
serves it at its root: https://h5p-player.example.net/?src=… -->
<iframe src="https://h5p-offline-player.vercel.app/embed?src=https://alekswebnet.github.io/h5p/gh-normalized.h5p&xapi=https://your-site.example"
allow="fullscreen; microphone; camera" style="width: 100%; border: 0"></iframe>
<!-- Optional, as the element's attributes: &libraries=pack &preload=auto
&frame©right&export&icon &fullscreen=off &reporting
&activity-id=<the IRI statements should name> &custom-css=<your stylesheet's URL>
&lang=<your page's language, for H5P's own buttons and dialogs> -->
<!-- Sizing: the frame reports its height in H5P's resizer protocol, and this one line
applies it. Served from this site, so your page sends nothing to a third party;
h5p.org's own h5p-resizer.js speaks the same protocol, if a page has it already. -->
<script src="https://h5p-offline-player.vercel.app/resizer.js"></script>
<!-- Or answer it yourself, and hear the statements: -->
<script>
const frame = document.querySelector('iframe')
addEventListener('message', ({ source, origin, data }) => {
if (source !== frame.contentWindow || origin !== 'https://h5p-offline-player.vercel.app') return
if (data.context === 'h5p' && data.action === 'hello') source.postMessage({ context: 'h5p', action: 'hello' }, origin)
if (data.context === 'h5p' && data.action === 'resize') frame.style.height = data.scrollHeight + 'px'
if (data.context === 'h5p-offline-player' && data.action === 'xapi') console.log(data.verb, data.statement)
})
</script>