Session replay for Vue and Nuxt

The recorder is a plain script with no dependencies, so Vue and Nuxt need no plugin package. Add one script tag, or load it from a small client-only plugin.

You need a running Replayowl server first. See Deploy to Cloudflare Workers. Below, replace replay.example.com with your server’s domain.

Vue with Vite

Add the script to index.html:

<script src="https://replay.example.com/recorder.js"
  data-endpoint="https://replay.example.com/api/ingest" defer></script>

Nuxt

Create a client-only plugin, plugins/replayowl.client.ts. The .client suffix makes Nuxt run it only in the browser:

export default defineNuxtPlugin(() => {
  const s = document.createElement("script");
  s.src = "https://replay.example.com/recorder.js";
  s.dataset.endpoint = "https://replay.example.com/api/ingest";
  s.defer = true;
  document.head.appendChild(s);
});

Leave out the endpoint and start the recorder yourself when the visitor agrees:

declare global {
  interface Window {
    ReplayOwl?: { start(o: { endpoint: string; userId?: string }): void; identify(id: string): void; stop(): void };
  }
}

export function startReplay(userId?: string) {
  const run = () => window.ReplayOwl?.start({ endpoint: "https://replay.example.com/api/ingest", userId });
  if (window.ReplayOwl) return run();
  const s = document.createElement("script");
  s.src = "https://replay.example.com/recorder.js";
  s.onload = run;
  document.head.appendChild(s);
}

Attaching the signed-in user

Call identify once you know who is signed in, for example in a watcher on your auth store:

watch(() => auth.user?.id, (id) => { if (id) window.ReplayOwl?.identify(id); }, { immediate: true });

The whole session is attributed to that user, including what happened before the call.

Masking components

<template>
  <p data-ro-mask>{{ account.iban }}</p>
  <div data-ro-block><SignaturePad /></div>
</template>

The attributes are read from the DOM, so they work on any element Vue renders. See Masking and privacy.

Route changes

Vue Router changes the page without a full load. Those changes are recorded and replayed, but the session’s page list only includes full page loads. See limitations.