Start

CDN quick start

Install the Releaseo widget with two script tags — no build step, no npm. A real, copy-paste walkthrough for adding the changelog, roadmap, and feature-request widget to any website.

The stable https://cdn.releaseo.io/sdk/v0/loader.js URL loads the current compatible v0 host runtime. Runtime fixes can therefore arrive automatically without changing the snippet on your site. If you use a build step and want the same update behavior with TypeScript, use the recommended @releaseo/sdk package.

30-second install — paste the snippet, the widget goes live.

You get the global window.releaseo runtime as soon as the loader script runs. Every function on it — init, identify, open, openFocused, track, and the rest — is documented in the SDK API reference.

1. Add the snippet

Paste this at the bottom of your page, right before the closing </body> tag. Swap in your own publish key from Settings → Widget → Install in the dashboard.

<!-- Releaseo widget — paste once, before </body> -->
<script src="https://cdn.releaseo.io/sdk/v0/loader.js"></script>
<script>
  window.releaseo.init({
    publishKey: "pk_live_3f9c2a7b8e1d4056a1b2c3d4",
  });
</script>

That is the entire install. Reload the page and the launcher appears in the bottom-right corner.

Where it sits in a real page

Here is exactly where those two tags go in a complete HTML document — everything else is your own site:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Acme</title>
  </head>
  <body>
    <!-- ↓ your existing site / app markup ↓ -->
    <header>…</header>
    <main>…</main>
    <footer>…</footer>

    <!-- ↓ Releaseo: load the SDK, then start it with your publish key ↓ -->
    <script src="https://cdn.releaseo.io/sdk/v0/loader.js"></script>
    <script>
      window.releaseo.init({
        publishKey: "pk_live_3f9c2a7b8e1d4056a1b2c3d4",
        theme: "auto", // follow the visitor's light/dark preference
        position: "right", // launcher corner: "left" or "right"
        locale: "en",
      });
    </script>
  </body>
</html>

2. Identify the signed-in visitor

If the visitor is logged in, tell Releaseo who they are so the widget can greet them and Contact can prefill safely. Render these values from your server session — never hardcode a real user.

<script>
  window.releaseo.init({ publishKey: "pk_live_3f9c2a7b8e1d4056a1b2c3d4" });

  // Example: values your backend printed for the logged-in user.
  window.releaseo.identify("u_8423", {
    name: "Sara Khalil",
    email: "sara@acme.com",
    tenantId: "acme",
  });
</script>

For verified identity in the dashboard Contact Inbox, also pass a userHash you generate server-side: HMAC_SHA256(CONTACT_IDENTITY_HMAC_SECRET, userId || email). Keep that secret on your server — never ship it to the browser.

3. Open a tab from your own button

Already have a “What’s new” link in your navbar? Wire it to the widget. This opens the changelog directly, with the tab bar hidden:

<button id="whats-new" type="button">What's new</button>

<script>
  document.getElementById("whats-new").addEventListener("click", function () {
    window.releaseo.openFocused("changelog");
  });
</script>

openFocused() accepts "home", "changelog", "feature_requests", "roadmap", or "help". Use plain window.releaseo.open() to open on the full tab bar.

4. Load without blocking your page

The snippet in step 1 is synchronous and simple. If you want to defer the SDK until after the page has loaded, use this instead of the snippet in step 1. The browser cannot call window.releaseo until loader.js has finished loading, so initialize it inside the script’s load handler.

<script>
  window.addEventListener(
    "load",
    function () {
      const script = document.createElement("script");
      script.src = "https://cdn.releaseo.io/sdk/v0/loader.js";
      script.async = true;
      script.addEventListener(
        "load",
        function () {
          window.releaseo.init({ publishKey: "pk_live_3f9c2a7b8e1d4056a1b2c3d4" });
          window.releaseo.identify("u_8423", {
            name: "Sara Khalil",
            email: "sara@acme.com",
          });
        },
        { once: true },
      );
      document.head.appendChild(script);
    },
    { once: true },
  );
</script>

Use the direct snippet when the launcher should appear as soon as possible. Use the deferred snippet when protecting first paint matters more than showing the launcher immediately.

Init options

init() resolves most settings from your dashboard, so publishKey is usually the only required field. Override these only when you need to:

OptionTypeExampleWhat it does
publishKeystring"pk_live_…"Your project key. Required.
theme"auto" | "light" | "dark""auto"Widget color scheme. auto follows the visitor.
position"left" | "right""right"Which corner the launcher sits in.
localestring"en"Widget language.
debugbooleantrueLogs verbose diagnostics to the console — handy while installing.

See the full ReleaseoInitConfig reference for every option, including consent and self-hosting.

Verify it’s working

  1. Reload your page — the launcher should appear in the corner you set.
  2. Click it; the widget drawer opens with your changelog and enabled tabs.
  3. Add debug: true to init() to print setup logs to the browser console if anything looks off.

In-app Launches

The same CDN install can show release announcements as a banner, toast, or modal on the host page. Configure the campaign in Releaseo; you do not need to mount a new component in your app. See In-app Launches for the right surface, targeting, event triggers, and manual triggerLaunch() calls.

Next steps

  • SDK API reference — every runtime function in detail.
  • In-app Launches — announce a shipped release with a banner, toast, or modal.
  • @releaseo/sdk — recommended typed npm facade with automatic compatible runtime updates.
  • @releaseo/sdk-core — advanced, version-pinned host runtime for your own bundle.
  • Integrations — connect GitHub repositories, route events to Slack and Discord, forward to PostHog, or deliver signed webhooks.
Was this page helpful?