Vue and Nuxt
Add relaybell to a Vue 3 app (Vite) or a Nuxt 3 site: load the SDK once, serve sw.js from public/, add a subscribe button and link signed-in users.
The browser SDK is a script tag that puts RelayBell on window. Load it once per page, serve relaybell's sw.js from your own domain, and call the SDK from your components when you need it. Your Project ID is on the dashboard's Install page.
Vue 3 with Vite
Paste the Quickstart snippet into index.html (at the project root), just before </body>:
<script src="https://relaybell.com/relaybell-sdk.js"></script>
<script>
RelayBell.init({ projectId: "YOUR_PROJECT_ID", apiBase: "https://relaybell.com" });
</script>The page loads it once and Vue Router changes pages without reloading it, so init() runs once per page load, as it should (a second call starts again from its own options). Your app's code runs after this script, so window.RelayBell is there when your components mount.
Then download sw.js and save it as public/sw.js: Vite serves public/ from the root of your site, so it opens at https://yoursite.com/sw.js, the default swPath.
Nuxt 3
Nuxt renders on the server, so load the SDK through the page head and let it start itself. Set the options in window.relaybellInit before the script: the SDK starts with them once it loads (on the page's load event, or straight away if that has passed).
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
script: [
{ innerHTML: 'window.relaybellInit = { projectId: "YOUR_PROJECT_ID", apiBase: "https://relaybell.com" };' },
{ src: "https://relaybell.com/relaybell-sdk.js", defer: true },
],
},
},
});Save sw.js as public/sw.js (Nuxt 3 serves public/ from the root). Call the SDK only in code that runs in the browser: onMounted(), event handlers, or a plugin named *.client.ts.
Note
Already have a service worker at /sw.js (a PWA module, for example)? Keep it: save relaybell's as public/relaybell/sw.js and add swPath: "/relaybell/sw.js", swScope: "/relaybell/" to the options. See Installing the SDK.
A subscribe button (optional)
relaybell shows your opt-in prompt by itself (Opt-in prompts). For your own button, call subscribeNow() from the click — browsers only show the permission prompt in answer to one:
<script setup>
import { onMounted, ref } from "vue";
const on = ref(false);
onMounted(async () => {
on.value = (await window.RelayBell?.isSubscribed()) === true;
});
async function subscribe() {
const result = await window.RelayBell?.subscribeNow();
if (result?.subscribed) on.value = true;
}
</script>
<template>
<p v-if="on">Notifications are on.</p>
<button v-else type="button" @click="subscribe">Turn on notifications</button>
</template>In Nuxt the SDK loads with defer and starts on the page's load event, so on the very first page it may not be there yet when onMounted() runs: the button then shows even for a subscribed browser. A click still works, since subscribeNow() waits for the SDK to finish starting.
Link signed-in users
To send to one of your users by your own user id, call identify() once you know who is signed in. With identity verification, pass the userHash your server made for that user (the HMAC-SHA256 of the id, keyed with your website's secret key); never put the secret key in the app.
// after sign-in, in browser code; user comes from your own auth code
window.RelayBell?.identify(user.id, user.relaybellHash);Calling it again with the same values does nothing. If you know the user when the page is rendered, you can put externalId and userHash into the init() options (or window.relaybellInit) instead. On a shared browser, call window.RelayBell?.unsubscribe() when someone signs out of a site without identity verification — see identify() under Methods.
Track events
track() feeds your automations and conversion reports:
window.RelayBell?.track("cart.updated", { productId: "1234", product: "Blue Shoes", price: 49, url: location.href });Or add autoCapture: true to the options: page views (including Vue Router page changes) and clicks on elements with data-rb-event are recorded for you. See Auto-capture.