How to use Sentry with Vue

Integrating Sentry with Vue applications provides real-time error tracking, performance monitoring, and detailed stack traces for production debugging. As the creator of CoreUI with over 12 years of Vue.js experience since 2014, I’ve integrated Sentry into numerous production Vue applications. Sentry captures errors automatically with context including user actions, browser info, and breadcrumbs leading to errors. This approach helps identify and fix production bugs quickly with comprehensive error data and alerting.

Install @sentry/vue and initialize in main.js to capture errors with context and source maps for production debugging.

Basic Sentry setup:

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import * as Sentry from '@sentry/vue'

const app = createApp(App)

Sentry.init({
  app,
  dsn: 'https://[email protected]/0',
  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.replayIntegration()
  ],
  // Performance Monitoring
  tracesSampleRate: 1.0,
  // Session Replay
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  environment: import.meta.env.MODE,
  enabled: import.meta.env.MODE === 'production'
})

app.mount('#app')

Advanced configuration:

// sentry.config.js
import * as Sentry from '@sentry/vue'
import { router } from './router'

export function initSentry(app) {
  Sentry.init({
    app,
    dsn: import.meta.env.VITE_SENTRY_DSN,
    integrations: [
      Sentry.browserTracingIntegration({ router }),
      Sentry.replayIntegration({
        maskAllText: false,
        blockAllMedia: false
      })
    ],
    tracesSampleRate: import.meta.env.MODE === 'production' ? 0.2 : 1.0,
    replaysSessionSampleRate: 0.1,
    replaysOnErrorSampleRate: 1.0,
    environment: import.meta.env.MODE,
    release: import.meta.env.VITE_APP_VERSION,
    enabled: import.meta.env.MODE !== 'development',
    beforeSend(event, hint) {
      // Filter out specific errors
      if (event.exception) {
        const error = hint.originalException
        if (error && error.message && error.message.includes('ResizeObserver')) {
          return null
        }
      }
      return event
    },
    ignoreErrors: [
      'Non-Error promise rejection',
      'ResizeObserver loop limit exceeded',
      'Network request failed'
    ]
  })

  // Set user context
  const user = getUserFromStorage()
  if (user) {
    Sentry.setUser({
      id: user.id,
      email: user.email,
      username: user.username
    })
  }
}

Error boundary component:

<script setup>
import { ref, onErrorCaptured } from 'vue'
import * as Sentry from '@sentry/vue'

const hasError = ref(false)
const errorMessage = ref('')

onErrorCaptured((err, instance, info) => {
  hasError.value = true
  errorMessage.value = err.message

  // Send to Sentry with context
  Sentry.captureException(err, {
    contexts: {
      vue: {
        componentName: instance?.$options?.name,
        propsData: instance?.$props,
        info
      }
    }
  })

  // Prevent error from propagating
  return false
})
</script>

<template>
  <div v-if="hasError" class="error-boundary">
    <h2>Something went wrong</h2>
    <p>{{ errorMessage }}</p>
    <button @click="hasError = false">Try Again</button>
  </div>
  <slot v-else />
</template>

Manual error reporting:

// api.service.js
import * as Sentry from '@sentry/vue'

export async function fetchUserData(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`)

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`)
    }

    return await response.json()
  } catch (error) {
    // Add breadcrumb
    Sentry.addBreadcrumb({
      category: 'api',
      message: 'Failed to fetch user data',
      level: 'error',
      data: { userId }
    })

    // Capture exception with context
    Sentry.captureException(error, {
      tags: {
        api_endpoint: '/api/users',
        user_id: userId
      },
      contexts: {
        response: {
          status: error.response?.status,
          statusText: error.response?.statusText
        }
      }
    })

    throw error
  }
}

Performance monitoring:

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import * as Sentry from '@sentry/vue'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    // routes
  ]
})

router.beforeEach((to, from, next) => {
  // Start performance transaction
  const transaction = Sentry.startTransaction({
    name: to.name,
    op: 'navigation',
    tags: {
      from: from.name,
      to: to.name
    }
  })

  // Attach transaction to route meta
  to.meta.sentryTransaction = transaction

  next()
})

router.afterEach((to) => {
  // Finish transaction
  const transaction = to.meta.sentryTransaction
  if (transaction) {
    transaction.finish()
  }
})

export { router }

Custom breadcrumbs:

<script setup>
import { onMounted } from 'vue'
import * as Sentry from '@sentry/vue'

const props = defineProps({
  userId: String
})

onMounted(() => {
  Sentry.addBreadcrumb({
    category: 'ui',
    message: 'User profile mounted',
    level: 'info',
    data: {
      userId: props.userId
    }
  })
})

const handleAction = () => {
  Sentry.addBreadcrumb({
    category: 'user-action',
    message: 'Button clicked',
    level: 'info'
  })

  // Perform action
}
</script>

Source maps for production:

// vite.config.js
import { defineConfig } from 'vite'
import { sentryVitePlugin } from '@sentry/vite-plugin'

export default defineConfig({
  build: {
    sourcemap: true
  },
  plugins: [
    sentryVitePlugin({
      org: 'your-org',
      project: 'your-project',
      authToken: process.env.SENTRY_AUTH_TOKEN,
      sourcemaps: {
        assets: './dist/**',
        ignore: ['node_modules']
      }
    })
  ]
})

Best Practice Note

Enable Sentry only in production to avoid noise during development. Upload source maps for readable stack traces in production. Use breadcrumbs to track user actions leading to errors. Set user context for better debugging. Filter out benign errors like ResizeObserver. Use performance monitoring to track slow routes. Tag errors with relevant context (API endpoints, user IDs). This is how we integrate Sentry in CoreUI Vue applications—comprehensive error tracking with context, source maps for debugging, performance monitoring, and filtered alerts ensuring we catch critical production issues without alert fatigue.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author