@vexia/vexia-widgets-lib
v1.0.1
Published
A lightweight DOM library for embedding Vexia competition widgets
Maintainers
Readme
Vexia Widgets Library
A lightweight Web/DOM library for embedding Vexia competition widgets in an iframe.
Installation
pnpm add @vexia/vexia-widgets-libUsage
NPM/TypeScript
import { createCompetitionIframe } from "@vexia/vexia-widgets-lib";
const container = document.getElementById("vexia-widget");
if (container) {
createCompetitionIframe(container, "YOUR_COMPETITION_ID");
}The iframe URL is generated as:
https://vexia-widgets--vexia-widgets.europe-west4.hosted.app/competitions/{competitionId}Browser Script
<div id="vexia-widget" style="height: 600px"></div>
<script src="https://cdn.jsdelivr.net/npm/@vexia/vexia-widgets-lib@1/dist/browser.min.js"></script>
<script>
VexiaWidgets.createCompetitionIframe(
document.getElementById("vexia-widget"),
"YOUR_COMPETITION_ID"
);
</script>API
createCompetitionIframe(target, competitionId, options?)
Creates an iframe and appends it to target.
Parameters:
target(HTMLElement) - DOM element that will receive the iframe.competitionId(string) - Competition ID used in the iframe URL.options(CreateCompetitionIframeOptions, optional) - iframe customization.
Options:
title- Accessible iframe title. Defaults to"Vexia competition widget".className- CSS class to add to the iframe.height- iframe height. Defaults to"100%".dynamicHeight- update iframe height when a matchingpostMessagepayload is received. Defaults totrue.dynamicHeightEventName- message type used for resizing. Defaults to"vexiaWidgetsIframeResizer".width- iframe width. Defaults to"100%".backgroundColor- background color applied to the iframe element. Defaults to"white".fullWidth- make the iframe span the viewport width even inside a narrower parent. Defaults tofalse.allow- iframe allow policy.allowFullscreen- whether fullscreen is allowed. Defaults totrue.
addCompetitionWidget is also exported as an alias of createCompetitionIframe.
Full Width
Use fullWidth: true when the iframe should visually span the viewport even if the target element is inside a centered or narrow parent.
createCompetitionIframe(container, "YOUR_COMPETITION_ID", {
fullWidth: true
});This applies viewport-width styles to the iframe. If an ancestor has overflow: hidden, the iframe can still be clipped by that ancestor.
Dynamic Height Message
By default, the library listens for message events from the iframe and only handles messages with type: "vexiaWidgetsIframeResizer".
Add this to the page rendered inside the iframe:
const VEXIA_RESIZE_MESSAGE_TYPE = "vexiaWidgetsIframeResizer";
function sendVexiaHeight() {
const height = Math.max(
document.documentElement?.scrollHeight ?? 0,
document.body?.scrollHeight ?? 0
);
window.parent.postMessage(
{
type: VEXIA_RESIZE_MESSAGE_TYPE,
detail: {
height
}
},
"*"
);
}
function startVexiaHeightReporter() {
const root = document.documentElement;
if (!(root instanceof Node)) {
return;
}
sendVexiaHeight();
window.addEventListener("load", sendVexiaHeight);
window.addEventListener("resize", sendVexiaHeight);
if ("ResizeObserver" in window) {
new ResizeObserver(sendVexiaHeight).observe(root);
}
if (document.body instanceof Node && "MutationObserver" in window) {
new MutationObserver(sendVexiaHeight).observe(document.body, {
attributes: true,
childList: true,
characterData: true,
subtree: true
});
}
}
if (document.readyState === "loading") {
window.addEventListener("DOMContentLoaded", startVexiaHeightReporter, {
once: true
});
} else {
startVexiaHeightReporter();
}The payload must match this shape:
window.parent.postMessage(
{
type: "vexiaWidgetsIframeResizer",
detail: {
height: 720
}
},
"*"
);Build
pnpm install
pnpm run buildExample
An Express example is available in examples/express-example.
