Skip to content

Framework integration

Session Replay for Vue and Nuxt Apps

Add session replay to Vue and Nuxt: start the browser SDK in main.ts or a client-only Nuxt plugin, record Vue Router changes, mask data and verify the install.

Updated · 4 min read

Vue session replay starts where your app is created: install @anyreplay/browser, create the recorder in a module and import it from main.ts. Nuxt session replay uses the same package inside a plugin whose file name ends in .client.ts, so it runs only in the browser. Vue Router and Nuxt route changes are recorded automatically.

Why add session replay to a Vue or Nuxt app

Reactive interfaces change a lot without a page load: a computed value hides a button, a watcher resets a form, a transition leaves an element half visible. Analytics tells you a step had fewer visitors; a recording shows the page as the visitor saw it, with every click and route change on a timeline. The recorder captures a DOM snapshot and the changes that follow, applies masking in the browser before sending, and never records your script bodies. When you have a few recordings, how to analyse session recordings covers what to look for.

How to install session replay in Vue 3

npm install @anyreplay/browser
import { createRecorder } from '@anyreplay/browser';

export const recorder = createRecorder({
  projectKey: import.meta.env.VITE_ANYREPLAY_KEY,
});
src/anyreplay.ts
import { createApp } from 'vue';
import './anyreplay';
import App from './App.vue';
import router from './router';

createApp(App).use(router).mount('#app');
src/main.ts

A module is evaluated once, so the recorder is created once. Do not call createRecorder inside a component's setup or onMounted: it does not guard against a second call, and every mount would start another recorder. Import recorder from components that need it.

How to install session replay in Nuxt 3

Nuxt renders on the server too, and the recorder needs a real document. A plugin named *.client.ts runs only in the browser, which is exactly where it belongs.

import { createRecorder } from '@anyreplay/browser';

export default defineNuxtPlugin(() => {
  const config = useRuntimeConfig();
  const recorder = createRecorder({
    projectKey: config.public.anyreplayKey as string,
  });
  return { provide: { recorder } };
});
plugins/anyreplay.client.ts

Add anyreplayKey: '' under runtimeConfig.public in nuxt.config.ts and set it with NUXT_PUBLIC_ANYREPLAY_KEY. Components reach the handle through useNuxtApp().$recorder. In a component that also renders on the server, $recorder does not exist there, so call it from event handlers or onMounted, which only run in the browser.

If you would rather not add a dependency, the script tag works too: put it in index.html for Vue or in app.head.script in nuxt.config.ts, and call window.anyreplay('track', …) instead of the handle.

Are Vue Router and Nuxt route changes recorded?

Yes. Vue Router in createWebHistory mode and Nuxt both navigate with the History API, and the recorder watches pushState, replaceState and back or forward navigation. Each real URL change becomes a page view with a $navigate marker. With createWebHashHistory, open a test session and check the route markers are there; if they are missing, add track calls from a router hook. See single-page apps.

How do I keep sensitive data out of recordings?

  • What people type is masked by default, v-model fields included. Pass maskAllInputs: false to record field values, or maskAllTyping: true to mask rich-text editors as well.
  • Passwords, one-time codes and payment fields are masked in every configuration; no option records them. type="email" and type="tel" inputs are not on that floor: they are ordinary fields, masked by default and recorded once you opt out.
  • Add class="ar-mask" to elements that display personal data, such as <dd class="ar-mask">{{ user.email }}</dd>, or to a single field to mask its value.
  • Add class="ar-block" to a section that should not be recorded at all; replay shows an empty box of the same size.
  • If your design system already has a class for sensitive fields, pass it as maskClass or blockClass. These replace the defaults.
  • Keep personal data out of track properties and URLs; neither is masked.

For a consent banner, pass requireConsent: true and call recorder.consent(true) when the visitor agrees. Nothing is recorded or sent before that. How to mask sensitive data in session recordings walks through an audit of a real page.

How do I check it is working?

  1. Start the app, open it in a browser and move between two routes.
  2. Open your project's setup page; it switches to Connected after the first accepted event.
  3. In the network panel, look for POST requests to in.anyreplay.com answered with 202.
  4. If nothing arrives, add debug: true to the options and read the console warnings.

The Vue and Nuxt install guide has the full files, and the npm package page lists every method on the handle.

Frequently asked questions

Can I add it without an npm dependency?

Yes. Paste the script tag from your project into index.html for Vue, or into app.head.script in nuxt.config.ts, and call window.anyreplay for events instead of the handle.

Why does Nuxt need a client-only plugin?

The recorder reads the live page, which does not exist during server rendering. A plugin whose name ends in .client.ts runs only in the browser.

Do I need a Vue Router integration?

No. With createWebHistory, route changes go through the History API and are recorded as page views automatically.

Are v-model inputs recorded?

Not by default: every field value replays as asterisks. Pass maskAllInputs: false to record values as typed; only a real boolean counts, so the string "false" from a tag manager variable is ignored and fields stay masked. Passwords, one-time codes and payment fields are masked whatever you pass; email and telephone fields follow maskAllInputs.

Start free — 1 project, 500 sessions a month

Install the snippet, record a session, and watch it back in your own language.