Install Flawsnap in a Vue app

Add the widget to the HTML shell once, then let a watcher on your user store tell Flawsnap who is reporting.

Steps

  1. 1

    Allow your hosts

    In the Flawsnap project’s Security settings, add your production and staging domains and localhost:5173 for the Vite dev server.

  2. 2

    Add the snippet to index.html

    Paste the snippet into the <head> of the index.html at the root of your Vite project.

  3. 3

    Declare the global

    Add a flawsnap.d.ts file so TypeScript knows about window.Flawsnap.

  4. 4

    Identify signed-in users

    Watch your user store and call window.Flawsnap?.identify() when it changes.

  5. 5

    Test a report

    Run npm run dev, click the button, mark up the page and send.

The snippet in index.html

The widget is a plain script, not a Vue plugin. Loading it beside your app rather than inside it means it is running before Vue mounts, so a crash during mount still shows up in the report's console tab.

Vite replaces %VITE_…% placeholders in index.html, so you can write data-key="%VITE_FLAWSNAP_KEY%" and keep the key per environment in .env files.

index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My Vue app</title>
    <script src="https://backend.flawsnap.com/widget.js" data-key="pk_…" async></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

Vue Router: nothing to add per route

Do not load the script in a route component or a beforeEach guard. Flawsnap follows navigation on its own by watching the History API. With createWebHistory(), every route change is recorded as a screen for Insights (Pro), and reports carry the current URL.

With createWebHashHistory(), the path never changes, so give screens names yourself after each navigation:

src/router/index.ts
router.afterEach((to) => {
  window.Flawsnap?.screen(String(to.name ?? to.path))
})

Identify from a Pinia store

Declare the global first:

src/flawsnap.d.ts
// flawsnap.d.ts (anywhere your tsconfig includes)
export {}

declare global {
  interface Window {
    Flawsnap?: {
      open(): void
      identify(reporter: { name?: string; email?: string }): void
      setMetadata(details: Record<string, unknown>): void
      screen(name: string): void
      track(name: string): void
      resetUser(): void
    }
  }
}

Then watch the user

A watcher in App.vue runs whenever the signed-in user changes, including after a page reload restores the session. immediate: true covers a user that is already known on load.

src/App.vue
<script setup lang="ts">
import { watch } from 'vue'
import { useAuthStore } from './stores/auth'

const auth = useAuthStore()
watch(
  () => auth.user,
  (user) => {
    if (user) window.Flawsnap?.identify({ name: user.name, email: user.email })
    else window.Flawsnap?.resetUser()
  },
  { immediate: true },
)
</script>

If the watcher runs before the widget has loaded, optional chaining skips the call. The next change to the user runs it again; for a guaranteed first call, queue it only while the widget isn’t there yet: const f = window.Flawsnap; if (f?.identify) f.identify(user); else ((window as any).Flawsnap ??= { q: [] }).q.push(['identify', user]).

Adding Vue errors to reports

Vue catches errors inside components and passes them to app.config.errorHandler. If you set a handler that swallows them, they never reach the console and Flawsnap cannot see them. Log them so the report shows them:

src/main.ts
app.config.errorHandler = (err, _instance, info) => {
  console.error(err, info)
}

Troubleshooting

  • [flawsnap] widget disabled: while developing: allow localhost:5173, or whatever port Vite printed when it started.
  • Two buttons or a warning about two copies: the tag is in index.html and also injected from code. Keep the index.html one.
  • CSP errors: allow https://backend.flawsnap.com in script-src and connect-src.

Questions

Is there a Vue plugin for Flawsnap?
No. The script tag is the whole install. Your Vue code only talks to window.Flawsnap for optional calls such as identify.
Does this work with Vue 2?
The widget does not depend on Vue at all, so the script tag works the same. Only the watcher example uses Vue 3 syntax.

Try it on your own site

7-day free trial, then $9 a month for Starter or $19 for Pro, per organization, with unlimited team members.

Updated