Skip to content

Bootstrap Loader

A small, dependency-free loader you embed before the main sesamy-js bundle to pre-fetch authentication state and optionally fall back to a secondary script origin.

When to use it

The bootstrap loader is optional. You can keep loading sesamy-js directly with a <script> tag. Add the loader when you want:

  • Faster first-paint auth on shared page caches where per-user SSR injection is not possible. The bootstrap starts the /auth/userinfo request in parallel with the main bundle instead of after it has loaded.
  • Multi-origin resilience with an optional fallback script URL.

What it does

  1. Reads cached userinfo from sessionStorage and the sesamy_is_authenticated session-hint cookie.
  2. If a fresh cache entry is available, resolves window.__sesamyBoot synchronously. Otherwise, if the hint cookie is set, kicks off /auth/userinfo in parallel with the main bundle and stashes the promise on window.__sesamyBoot. The main bundle consumes this instead of starting its own fetch.
  3. Injects the full script chain publishers need for a working sesamy-js app — auth0-plugin (for SPA auth), capsule-plugin (when DCA is enabled), sesamy-components, and the sesamy-js core — in that order. Scripts download in parallel but execute sequentially, so the core sees the plugin factories on window before it auto-inits.
  4. If the core script fails or the primary origin never signals load success (via a synchronous window.__sesamyLoaded sentinel set by the core, or window[namespace] after init() runs) within a timeout, an optional fallback bundle is loaded instead.

Which plugins are fetched is inferred from the <script id="sesamy-js"> config:

  • auth0-plugin — loaded unless auth.useHttpCookies: true (cookie/BFF auth uses server-side handlers instead).
  • capsule-plugin — loaded only when capsule.enabled: true.
  • sesamy-components — always, unless skipComponents: true.

You can override each decision with the loadAuth0Plugin, loadCapsulePlugin, and skipComponents bootstrap options.

Usage

The bootstrap must be inlined in the <head>. Loading it from an external <script src> would add a round-trip before the prefetch starts, which defeats the purpose. The package ships a renderBootstrapScript() helper that returns an inline-ready script body with your options baked in — call it from your SSR template:

typescript
import { renderBootstrapScript } from '@sesamy/sesamy-js/bootstrap';

const bootstrap = renderBootstrapScript({
  clientId: 'your-client-id',
});

const html = `
  <head>
    <script>${bootstrap}</script>
    <script type="application/json" id="sesamy-js">
      {
        "clientId": "your-client-id",
        "vendorId": "your-vendor-id",
        "auth": { "useHttpCookies": true },
        "capsule": { "enabled": true }
      }
    </script>
  </head>
`;
html
<head>
  <script type="application/json" id="sesamy-js">
    {
      "clientId": "your-client-id",
      "vendorId": "your-vendor-id",
      "auth": { "useHttpCookies": true },
      "capsule": { "enabled": true }
    }
  </script>
  <script>
    /* paste the contents of @sesamy/sesamy-js/dist/bootstrap.iife.js here */
  </script>
</head>

In the static HTML / WordPress case, the bootstrap auto-runs at the end of its IIFE. It reads the <script id="sesamy-js"> element and calls itself with the bootstrap-relevant keys (clientId, environment, version, per-entry version overrides, fallbackSrc, namespace, and the plugin/component load overrides), so you do not need a second inline call. Place the config element before the bootstrap script — the parser runs them in document order, and the bootstrap needs to read auth.useHttpCookies and capsule.enabled to pick the right plugins.

clientId vs vendorId

clientId identifies your sesamy-js integration (and drives the main bundle URL). vendorId identifies the publisher tenant within Sesamy and is required by the main bundle for entitlements, paywalls, and JWKS lookup. In some tenants the two strings are identical, but you should treat them as independent — check the Sesamy dashboard if you are not sure.

Where each option is read

The bootstrap and the main bundle both read <script id="sesamy-js">, but they look at different keys:

  • The bootstrap reads the bootstrap-relevant keys when auto-running from the IIFE: clientId, environment, version, componentsVersion, auth0PluginVersion, capsulePluginVersion, src, fallbackSrc, fallbackTimeoutMs, apiBaseUrl, namespace, skipAuthPrefetch, skipComponents, loadAuth0Plugin, loadCapsulePlugin, debug. It also reads auth.useHttpCookies and capsule.enabled to infer which plugin scripts to fetch, and auth.baseUrl to keep the {auth.baseUrl}/auth/userinfo prefetch URL aligned with the runtime BFF plugin. SSR templates can pass the same keys to renderBootstrapScript({ … }) instead.
  • The main bundle reads the full config (vendorId, auth, capsule, environment, content, etc.) from the same element after it loads.

The clientId drives all chain URLs — the loader resolves it to https://scripts.sesamy.com/s/{clientId}/{name}/{version}.js via the Scripts Host for each of auth0-plugin, capsule-plugin, sesamy-components, and sesamy-js. Pass version to pin a specific channel or version, environment: 'dev' to switch the origin to scripts.sesamy.dev, or src to override just the core URL (the chain is skipped when src is set, so use this only when pointing at a self-contained bundle).

auth0-plugin, capsule-plugin, and sesamy-components release on independent tracks from sesamy-js core, so a specific semver like version: '1.118.1' (a sesamy-js release) will not resolve for the other chain entries. Use the per-entry overrides auth0PluginVersion, capsulePluginVersion, and componentsVersion to pin one entry while leaving the others on latest / stable. Each override falls back to version when omitted.

renderBootstrapScript() serialises the function via .toString() and bakes in the options via JSON.stringify(), so the output is a self-contained IIFE. Re-run the helper whenever you render the page — it is cheap.

Options

FieldTypeDescription
clientIdstringYour Sesamy client id. When set, the chain URLs default to https://scripts.sesamy.com/s/{clientId}/{name}/{version}.js. Either clientId or src is required.
versionstring(Optional) Version channel served by the Scripts Host, applied to every script in the chain. Defaults to stable. Accepts stable, latest, or a specific version.
componentsVersionstring(Optional) Per-entry version override for sesamy-components. Falls back to version when omitted. Use when pinning a specific sesamy-js semver — components release on their own track.
auth0PluginVersionstring(Optional) Per-entry version override for auth0-plugin. Falls back to version.
capsulePluginVersionstring(Optional) Per-entry version override for capsule-plugin. Falls back to version.
environment'dev' | 'prod'(Optional) Scripts-host origin for clientId resolution. prod (default) uses scripts.sesamy.com; dev uses scripts.sesamy.dev. Ignored when src is set.
srcstring(Optional) Override the primary core bundle URL. Loads only this one script and skips the plugin/components chain — use when pointing at a self-contained bundle or custom CDN.
fallbackSrcstring(Optional) URL of a secondary bundle loaded if the core script fails or times out.
fallbackTimeoutMsnumber(Optional) Milliseconds before the fallback is attempted. Defaults to 3000.
apiBaseUrlstring(Optional) Base URL for the /auth/userinfo prefetch. When omitted, the bootstrap reads auth.baseUrl from the page config so the prefetch matches the runtime BFF plugin's URL (e.g. /sesamy/auth/userinfo). Falls back to same-origin when neither is set. Set explicitly only when the prefetch should target a different host than the runtime BFF plugin.
namespacestring(Optional) The global the main bundle installs on window. Defaults to sesamy. Must match api.namespace in your sesamy-js config.
skipAuthPrefetchboolean(Optional) Skip the userinfo prefetch. Use when the page already injects a <script id="sesamy-server-state"> element for SSR auth.
skipComponentsboolean(Optional) Skip loading sesamy-components. Only useful if you are hosting a custom build of the web components.
loadAuth0Pluginboolean(Optional) Force-enable or force-disable the auth0-plugin script. When unset, the bootstrap inspects auth.useHttpCookies in the config element and loads the plugin unless cookie auth is enabled. Pass an explicit value when your SSR template renders the bootstrap before the <script id="sesamy-js"> element.
loadCapsulePluginboolean(Optional) Force-enable or force-disable the capsule-plugin script. When unset, follows capsule.enabled from the config element.
debugboolean(Optional) When true, emits [sesamy-boot] log lines to the console for key decisions: chain entry selection and source (option vs. config), userinfo prefetch source, per-script load/error events, and fallback trigger reason. Useful for diagnosing chain regressions without a HAR capture. Off by default; zero runtime overhead when unset.

Targeting the dev stack

Publishers testing against the Sesamy dev environment need to resolve clientId to scripts.sesamy.dev rather than scripts.sesamy.com. Pass environment: 'dev':

typescript
const bootstrap = renderBootstrapScript({
  clientId: 'your-client-id',
  environment: 'dev',
});

For more bespoke setups (custom CDN, version-pinned mirror) use src to override the bundle URL entirely. Remember to also switch the main bundle's environment to dev in <script id="sesamy-js"> so the two halves agree on which API origin to hit.

Fallback origin

The fallbackSrc option is provided for future multi-cloud deployments. Today, the primary origin is served by Cloudflare. If you configure a fallback, both the script origin and the Sesamy API it calls need to live on independent infrastructure for the failover to be meaningful, so only use this option if you have verified both ends.

Fallback origin is opt-in

Enabling fallbackSrc without a working secondary origin is harmless (the timer fires but finds no script to load), but it does not add resilience on its own. Treat it as plumbing to enable when an independent fallback is available.

How it interacts with SSR

The bootstrap and the Server-Side Rendering pattern solve overlapping but distinct problems:

  • SSR id-token injection is the fastest option when your server renders per-user HTML. It skips the /auth/userinfo round-trip entirely.
  • The bootstrap is the right choice when your HTML is shared across users (edge cache, static hosting) and per-user SSR injection is not possible.

If you use both, set skipAuthPrefetch: true on the bootstrap to avoid the unnecessary userinfo call when a valid sesamy-server-state element is already present.

Next Steps

Released under the MIT License.