@alakazamworld/embed
v0.1.0
Published
Embed an Alakazam programmable world in your own site or app.
Maintainers
Readme
@alakazamworld/embed
Drop an Alakazam programmable world into your own site or app — and react to its events to wire it into your own logic. Zero dependencies; works with any framework. Part of the Alakazam programmable worlds API.
Install
npm install @alakazamworld/embedOr via a script tag (auto-inits [data-alakazam-slug] elements):
<div data-alakazam-slug="my-world" data-alakazam-token="SESSION_TOKEN"></div>
<script src="https://cdn.alakazam.gg/embed.global.js"></script>The two-token rule (important)
- Your secret API key (
sk_…) stays on your server. Never ship it to a browser. - Your server calls
POST /v1/sessions/tokenwith the secret key to mint a short-lived session token, and hands that to the browser. @alakazamworld/embedtakes the session token and boots the world.
// your backend
const r = await fetch("https://api.alakazam.gg/v1/sessions/token", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.ALAKAZAM_SECRET_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ worldId, playerIdentity: user.id, origin: "https://yourgame.com" }),
});
const { token } = await r.json(); // send `token` to the browserUsage
import { createEmbed } from "@alakazamworld/embed";
const embed = createEmbed({
container: "#game",
slug: "my-world",
token, // the session token from your backend
theme: { colorPrimary: "#86ffba" },
onReady: () => console.log("playing"),
onChoice: (c) => console.log("player chose", c),
onEnding: (e) => console.log("ending reached", e),
onSessionEnded: () => console.log("session over"),
// Re-authorization checkpoint: return a fresh token from your backend.
onTokenExpiring: async () => (await fetch("/api/alakazam-token").then(r => r.json())).token,
});
// later
embed.destroy();Theming (US-305)
Pass a theme to createEmbed and it is applied two ways so the player chrome
is themed from the very first paint with no flash:
- At boot — encoded as a base64-JSON
?theme=query param on the iframe URL. - At runtime — call
embed.setTheme({ ... })to post athememessage to the running embed.
embed.setTheme({ colorPrimary: "#ff7ad9", borderRadius: "12px" });Theme tokens: colorPrimary, colorBackground, colorText, fontFamily,
borderRadius (plus any extra string tokens).
Embedding security (US-307)
The postMessage bridge is origin-validated on both ends:
- Inbound — a message is dropped unless
event.originis exactly the embed base origin and it carries the SDK envelope (sourcemarker + stringtype). Cross-origin or malformed messages are ignored. - Outbound — token and theme posts target the exact embed origin
(
new URL(baseUrl).origin), never the wildcard'*', so a session token can never leak to a navigated/foreign frame.
Your secret key never touches the browser (see the two-token rule above); only a short-lived session token does.
Note: the short-lived session token is delivered to the embed surface via the iframe URL's
tokenquery param by design — so the embed host should avoid logging that URL (or itstokenparam) into request/access logs or analytics. This is the documented tradeoff of URL-based token delivery.
Events
onReady, onChoice, onStateEntered, onEnding, onSessionEnded,
onHeightChanged, onError, onTokenExpiring. All are delivered over the
origin-validated postMessage channel described above.
API
createEmbed(options) → { iframe, destroy(), setTheme(theme), sendToken(token) }
Pure helpers (also exported, used internally and in the smoke test):
encodeTheme(obj) → string, isTrustedEmbedMessage(eventOrigin, expectedOrigin, data) → boolean.
Test
npm test # node test/smoke.mjs — dependency-free, runs against the built dist