Skip to content

No bundler, no build step: one script tag gives you the Frak web components and the full SDK on window.

  1. A merchant account on the Frak business dashboard with your domain registered. The main domain is registered at sign-up; add subdomains under Allowed Domains.
  2. Any HTML page you can add a script tag to.

If you have not done that yet, start with the Get started guide.

BundleURLWhat it is
Componentshttps://cdn.jsdelivr.net/npm/@frak-labs/components@latestESM. Registers the <frak-*> elements, boots the SDK, and exposes the SDK on window.FrakSetup.core. This is the one you want.
Core onlyhttps://cdn.jsdelivr.net/npm/@frak-labs/core-sdk@latest/cdn/bundle.jsIIFE exposing window.FrakSDK. No UI, no auto-boot. Only for a page that drives the SDK entirely by hand.

The rest of this page uses the components bundle.

The loader reads window.FrakSetup.config when it boots, so the config object must exist before the script tag runs.

index.html
<head>
<!-- 1. Configure Frak -->
<script>
window.FrakSetup = {
config: {
metadata: {
name: "Your Store",
currency: "eur",
},
},
};
</script>
<!-- 2. Load the components (registers the elements and boots the SDK) -->
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@frak-labs/components@latest"
defer="defer"
></script>
</head>

type="module" is required: the components bundle is ESM.

FieldDefaultMeaning
env"prod"The environment to run against: "prod", "dev", or { wallet, backend }.
metadata.namenoneYour application name, shown in modals and SSO.
metadata.merchantIdresolved from your domainYour merchant ID (UUID) from the dashboard.
metadata.currency"eur""eur", "usd", or "gbp".
metadata.langbrowser language"en" or "fr".
metadata.logoUrlnoneLogo used by some components.
metadata.homepageLinknoneFallback link used by some components.
domainwindow.location.hostOverride only if the page host differs from your registered domain.
customizations.cssnoneURL of a stylesheet applied to the modals and components.
customizations.i18nnoneInline translation overrides, per locale or flat.
waitForBackendConfigtrueWait for the backend configuration before rendering components.
attributionnoneDefault UTM, via, and ref values appended to sharing URLs.
preload["sharing"]Views preloaded inside the listener iframe. Pass [] to disable.

See Configuration and FrakSetup for the full reference.

The loader watches the DOM, so an element added at any time registers itself:

<body>
<frak-banner></frak-banner>
<frak-button-share classname="button"></frak-button-share>
</body>

Every element and attribute is documented in the components reference.

Once booted, the SDK publishes two things:

  • window.FrakSetup.client, the client instance
  • window.FrakSetup.core, every SDK function and action

The client is created asynchronously, so wait for the frak:client event before using it:

<script>
function waitForClient() {
if (window.FrakSetup?.client) return Promise.resolve(window.FrakSetup.client);
return new Promise((resolve) => {
window.addEventListener(
"frak:client",
() => resolve(window.FrakSetup.client),
{ once: true }
);
});
}
(async () => {
const client = await waitForClient();
// Watch the wallet status
await window.FrakSetup.core.watchWalletStatus(client, (status) => {
console.log(status.key === "connected" ? status.wallet : "not connected");
});
// Open a modal
await window.FrakSetup.core.displayModal(client, {
steps: {
login: {},
final: { action: { key: "sharing" } },
},
});
})();
</script>

trackPurchaseStatus is the exception: it takes no client, so you can call it as soon as the SDK is loaded.

<script>
window.addEventListener("frak:client", () => {
window.FrakSetup.core.trackPurchaseStatus({
customerId: "cust_123",
orderId: "order_456",
token: "a-unique-order-token",
});
});
</script>

Rewards are only released once your backend confirms the order with a signed webhook. See Validate purchases from your backend.

EventTargetDetailFired when
frak:clientwindownoneThe client is ready, window.FrakSetup.client is set
frak:configwindowthe resolved configThe backend configuration is resolved or refreshed
frak:referral-successwindownoneAn inbound referral was processed successfully

The loader also handles ?frakAction=share on page load, with optional link, products, and placement parameters. It opens the sharing flow and then strips those parameters from the URL. That is how a link out of an email or a QR code can open the share sheet directly.

If you do not want the components at all, load the core bundle and create the client yourself:

<script src="https://cdn.jsdelivr.net/npm/@frak-labs/core-sdk@latest/cdn/bundle.js"></script>
<script>
let clientPromise;
function getClient() {
// Call setupClient once. Each call recreates the listener iframe.
clientPromise ??= FrakSDK.setupClient({
config: { metadata: { name: "Your Store" } },
});
return clientPromise;
}
(async () => {
const client = await getClient();
if (!client) return;
await FrakSDK.watchWalletStatus(client, console.log);
})();
</script>

window.FrakSDK carries the same functions and actions as window.FrakSetup.core. It exists only for this bundle: the components bundle is ESM and exposes no global.