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.
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
- Vue With Vite
- Nuxt 3
- Routing
- Identify Users and Track Events
- Masking
- Vue-Specific Things to Check
- 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-srcandconnect-src(CSP guide).
Key Takeaways
- One script tag in
index.html, or one entry innuxt.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.
Frequently Asked Questions
Related articles
Stay in the loop
Get the latest insights on product analytics and user behavior delivered to your inbox.



