Package

@releaseo/react

Headless React adapter for Releaseo, with provider state, widget actions, unread count, and SSR-safe snapshots.

Install

npm install @releaseo/sdk @releaseo/react

Provider

The adapter is headless. It initializes @releaseo/sdk, exposes React state and actions, and keeps the update UI inside the Releaseo iframe.

import { ReleaseoProvider } from "@releaseo/react";

export function App() {
  return (
    <ReleaseoProvider config={{ publishKey: "pk_live_xxx" }}>
      <AppShell />
    </ReleaseoProvider>
  );
}

For tenant, organization, or project switches, pass a stable resetKey.

<ReleaseoProvider config={releaseoConfig} resetKey={`${tenant.id}:${project.id}`}>
  <AppShell />
</ReleaseoProvider>

Use resetOnUnmount only when the provider is intentionally tied to a route or microfrontend lifecycle and should tear down the SDK after unmount.

Version behavior

The React adapter and @releaseo/sdk facade stay pinned in your package lock. The facade loads the compatible host runtime from Releaseo’s stable /sdk/v0/ CDN channel, so compatible runtime fixes can arrive without reinstalling the adapter. Upgrade the npm packages when you need adapter, facade, type, or public API changes.

Open button and unread count

import { useReleaseo, useReleaseoUnread } from "@releaseo/react";

export function WhatsNewButton() {
  const { isReady, open } = useReleaseo();
  const unread = useReleaseoUnread();

  return (
    <button type="button" disabled={!isReady} onClick={() => void open()}>
      What's new {unread > 0 ? `(${unread})` : null}
    </button>
  );
}

Identity sync

Use useReleaseoIdentity() after auth and tenant context are known.

import { useReleaseoIdentity } from "@releaseo/react";

export function ReleaseoIdentitySync({ viewer, workspace }: Props) {
  useReleaseoIdentity({
    userId: viewer?.id,
    enabled: Boolean(viewer && workspace),
    identityKey: viewer && workspace ? `${viewer.id}:${workspace.id}` : null,
    properties:
      viewer && workspace
        ? { email: viewer.email, name: viewer.name, workspaceId: workspace.id }
        : undefined,
    logoutOnDisable: true,
  });

  return null;
}

identityKey controls when the hook calls identify(). Include tenant or organization ids when those should create a new SDK session.

Hooks

HookPurpose
useReleaseo()Full snapshot plus runtime actions.
useReleaseoStatus()Derived status such as idle, ready, identified, or error.
useReleaseoUnread()Current unread count from the widget.
useReleaseoSettings()Resolved SDK/widget settings snapshot.
useReleaseoError()Runtime error state.
useReleaseoIdentity(options)Safe viewer identity handoff.
useReleaseoSelector(selector)Subscribe to a narrow slice of SDK state.

Next.js App Router

Render the provider from a client component.

"use client";

import { ReleaseoProvider } from "@releaseo/react";

export function ReleaseoClientProvider({ children }: { children: React.ReactNode }) {
  return <ReleaseoProvider config={{ publishKey: "pk_live_xxx" }}>{children}</ReleaseoProvider>;
}

The adapter is SSR-safe. Server rendering receives an idle snapshot and runtime work starts from client-side effects.

Client-side navigation works automatically — the underlying SDK detects DOM swaps and re-attaches its launcher, iframe, and stylesheet. For zero-flicker persistence, add a <div data-releaseo-host /> sentinel inside app/layout.tsx so the SDK mounts inside the stable layout DOM. See Installation → SPA frameworks for details.

Was this page helpful?