Package

@releaseo/vue

Headless Vue 3 adapter for Releaseo, with createReleaseo plugin setup, composables, unread count, identity sync, and SSR-safe runtime behavior.

Install

npm install @releaseo/sdk-core @releaseo/vue

Package link: @releaseo/vue on npm

Plugin

The adapter is headless. It initializes @releaseo/sdk-core, exposes Vue composables, and keeps the update UI inside the Releaseo iframe.

import { createApp } from "vue";
import { createReleaseo } from "@releaseo/vue";
import App from "./App.vue";

createApp(App)
  .use(createReleaseo({ config: { publishKey: "pk_live_xxx" } }))
  .mount("#app");

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

app.use(
  createReleaseo({
    config: releaseoConfig,
    resetKey: () => `${tenant.value?.id ?? "none"}:${project.value?.id ?? "none"}`,
  }),
);

Use disabled when auth or workspace state is not ready yet. Use resetOnUnmount only when the Vue app instance intentionally owns the shared SDK lifecycle and should tear it down after unmount.

Open button and unread count

<script setup lang="ts">
import { useReleaseo, useReleaseoUnread } from "@releaseo/vue";

const { isReady, open } = useReleaseo();
const unread = useReleaseoUnread();
</script>

<template>
  <button type="button" :disabled="!isReady" @click="void open()">
    What's new {{ unread > 0 ? `(${unread})` : "" }}
  </button>
</template>

Identity sync

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

<script setup lang="ts">
import { computed } from "vue";
import { useReleaseoIdentity } from "@releaseo/vue";

const props = defineProps<{
  viewer: { id: string; email: string; name?: string; releaseoUserHash?: string } | null;
  workspace: { id: string; plan?: string } | null;
}>();

const identityKey = computed(() =>
  props.viewer && props.workspace ? `${props.viewer.id}:${props.workspace.id}` : null,
);

useReleaseoIdentity({
  userId: () => props.viewer?.id ?? null,
  enabled: () => Boolean(props.viewer && props.workspace),
  identityKey,
  properties: () =>
    props.viewer && props.workspace
      ? {
          email: props.viewer.email,
          name: props.viewer.name,
          workspaceId: props.workspace.id,
          plan: props.workspace.plan,
          userHash: props.viewer.releaseoUserHash,
        }
      : undefined,
  logoutOnDisable: true,
});
</script>

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

Composables

ComposablePurpose
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.
useReleaseoEvent(eventName, handler)Subscribe to SDK runtime events.
useReleaseoSelector(selector)Subscribe to a narrow slice of SDK state.

Nuxt 3

Register the adapter from a client plugin.

// plugins/releaseo.client.ts
import { createReleaseo } from "@releaseo/vue";

export default defineNuxtPlugin((nuxtApp) => {
  const config = useRuntimeConfig();

  nuxtApp.vueApp.use(
    createReleaseo({
      config: {
        publishKey: config.public.releaseoPublishKey,
      },
    }),
  );
});

The adapter is SSR-safe. Server rendering receives an idle snapshot, and runtime work starts only after the plugin is installed in the browser.

Client-side navigation works automatically - the underlying SDK detects DOM swaps and re-attaches its launcher, iframe, and stylesheet. For zero-flicker persistence, render a <div data-releaseo-host /> sentinel inside the stable Vue or Nuxt layout. See Installation - SPA frameworks for details.

Was this page helpful?