Product

Session Replay and Heatmaps for Vue and Nuxt

Add session replay and heatmaps to a Vue or Nuxt 3 application. Covers where to place the loader, how Vue Router navigation is captured, identifying users, custom events, and masking sensitive components.

Purushottam Kumar Suman
Purushottam Kumar SumanSeptember 13, 20266 min read
Founder & CEO, DeepSync
Vue application code with session replay setup

Short answer: in a Vue app built with Vite, add the loader script tag to index.html. In Nuxt 3, add it to the app.head.script array in nuxt.config.ts. Vue Router navigations are captured automatically, so you do not need a router guard. Then identify logged-in users, track a few outcome events, and mask anything sensitive your components display.

Table of Contents

  1. Vue With Vite
  2. Nuxt 3
  3. Routing
  4. Identify Users and Track Events
  5. Masking
  6. Vue-Specific Things to Check
  7. Key Takeaways

Vue With Vite

There is nothing Vue-specific to configure. Put the loader in the HTML shell that serves the app:

<!-- index.html -->
<head>
  <script async src="YOUR_LOADER_URL"></script>
</head>

Your loader URL is in your project's install settings. The async attribute keeps it from blocking rendering. Full reference: Install in Vue or Nuxt.

Placing it in index.html, instead of injecting it from a component, means recording begins before the app mounts, so the first moments of a visit are captured.

Nuxt 3

Add the script through the app head configuration, which puts it on every page:

// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      script: [{ src: "YOUR_LOADER_URL", async: true }],
    },
  },
});

Whether a page was server-rendered, statically generated, or rendered on the client makes no difference. The recorder runs in the browser and captures the DOM the visitor actually sees.

Routing

The SDK patches the browser's History API, so every Vue Router navigation is recorded as a page view. You do not need an afterEach guard or any manual page tracking.

That means:

  • Each route appears as its own page in session timelines.
  • Heatmaps are built per route.
  • Funnels can use route paths as steps.

Dynamic routes such as /projects/:id are recorded with their real URLs. Group them when you analyse a template.

For steps that do not change the URL, such as tabs inside a page or a multi-step modal, use a custom event (SPA guide).

Identify Users and Track Events

Call identify once you know who the user is, for example after your auth store resolves:

deepsync("identify", user.id, {
  plan: "pro",
  signupDate: user.createdAt,
});

Run it once per user, not on every route change. In Nuxt, call it from client-side code only, since it depends on the browser.

Track outcomes the script cannot infer:

deepsync("track", "project_created");

These become targets for goals and steps in funnels. See the SDK API.

The loader is asynchronous. If your app may call the SDK before it has loaded, add the command-queue stub described in how the SDK works so early calls are buffered.

Masking

Passwords, payment fields, and text inputs are masked in the browser by default. For data your components render, add a class in the template:

<span class="ds-mask">{{ customer.email }}</span>

<div class="ds-block">
  <InvoicePreview :invoice="invoice" />
</div>

ds-mask replaces the text in replay. ds-block excludes the element entirely. Details in PII masking.

If your project uses consent-required mode, which is the default, call the consent function from your cookie banner. Until it fires, nothing is recorded (consent modes).

Vue-Specific Things to Check

  • Transitions. Elements entering with a transition are captured at their starting state for a moment. If a recording shows content missing that the visitor clearly interacted with, an entrance animation is the likely cause (capture limits).
  • Teleport. Modals teleported to the body are part of the DOM and recorded normally.
  • Large reactive lists. Frequent re-renders of long lists produce a lot of mutation data. Virtual scrolling helps users and reduces recording volume.
  • Hydration. In Nuxt, the page is visible before it is interactive. Clicks during that gap that do nothing show up as dead clicks, which is useful to know.
  • Canvas-based charts. Chart libraries that draw on a canvas will not appear in replay. SVG charts will.
  • Content Security Policy. If you set one, allow the ingest origin in script-src and connect-src (CSP guide).

Key Takeaways

  • One script tag in index.html, or one entry in nuxt.config.ts.
  • Vue Router navigation is tracked automatically.
  • Identify users once and track a few outcome events.
  • Mask rendered personal data with a class in the template.

Conclusion

Vue and Nuxt need no special integration. Add the tag, mask what is sensitive, and you can see how people use what you built.

Start free · Install in Vue or Nuxt

Frequently Asked Questions

Was this article helpful?

Ready to understand
users like never before?

Join thousands of teams who use DeepSync to uncover insights,improve experiences, and build better products—faster.

Quick & easy onboarding
See results in real time
Enterprise-grade security