TraceKit Vue SDK Setup
When To Use
Use this skill when the user asks to:
- Add TraceKit to a Vue.js application
- Add observability or APM to a Vue app
- Instrument a Vue project with error tracking or distributed tracing
- Configure TraceKit API keys in a Vue project
- Set up Vue error handlers with automatic error reporting
- Add performance monitoring to a Vue app
- Debug production Vue apps with live breakpoints
Not Vue? If the user is using React, Angular, Next.js, Nuxt, or a plain JS/TS project without a framework, use the corresponding skill instead. If the user is using Nuxt, use the tracekit-nuxt-sdk skill -- it provides SSR-aware initialization.
Non-Negotiable Rules
- Never hardcode API keys in code. Always use environment variables or build-time injection (e.g.,
import.meta.env.VITE_TRACEKIT_API_KEY). - Always include a verification step confirming errors and traces appear in
https://app.tracekit.dev/traces. - Always enable code monitoring (
enableCodeMonitoring: true) — it is TraceKit's differentiator for live debugging. - Always init TraceKit before mounting the app — the plugin must be registered with
app.use()beforeapp.mount().
Detection
Before applying this skill, detect the project type:
- Check for
package.json— confirms this is a JavaScript/TypeScript project. - Check for
vueindependencies— confirms this is a Vue project. - Check for Nuxt: If
nuxtis in dependencies, use thetracekit-nuxt-sdkskill instead. - Detect Vue version:
- Check
main.tsormain.jsforcreateAppusage => Vue 3 (use Composition API examples) - Check for
new Vueusage => Vue 2 (use Options API examples) - Check
vueversion inpackage.json:^3.x= Vue 3,^2.x= Vue 2
- Check
- Check for TypeScript:
tsconfig.jsonpresence means use.tssnippets. - Only ask the user if Vue version cannot be determined.
Step 1: Environment Setup
Set the TRACEKIT_API_KEY environment variable. This is the only required secret.
Add to your .env file:
VITE_TRACEKIT_API_KEY=ctxio_your_api_key_here
Vue CLI projects (Webpack-based):
VUE_APP_TRACEKIT_API_KEY=ctxio_your_api_key_here
Where to get your API key:
- Log in to TraceKit
- Go to API Keys page
- Generate a new key (starts with
ctxio_)
Do not commit real API keys. Use .env files, deployment secret managers, or CI variables.
Step 2: Install SDK
npm install @tracekit/vue
Or with Yarn:
yarn add @tracekit/vue
This installs the TraceKit Vue SDK which wraps @tracekit/browser with Vue-specific integrations: plugin pattern, error handler chaining, router breadcrumbs, and Composition API composables. You only need this one package.
Step 3: Initialize TraceKit Plugin
Register the TraceKitPlugin with your Vue app. The plugin handles SDK initialization, error handler setup, and optional router breadcrumbs in a single app.use() call.
Vue 3 (Composition API)
// src/main.ts
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import { TraceKitPlugin } from '@tracekit/vue';
import App from './App.vue';
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: () => import('./views/Home.vue') },
{ path: '/dashboard', component: () => import('./views/Dashboard.vue') },
],
});
const app = createApp(App);
// Register TraceKit BEFORE mounting
app.use(TraceKitPlugin, {
apiKey: import.meta.env.VITE_TRACEKIT_API_KEY,
serviceName: 'my-vue-app',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
release: import.meta.env.VITE_APP_VERSION || '0.0.0',
environment: import.meta.env.MODE,
router, // enables automatic route change breadcrumbs
});
app.use(router);
app.mount('#app');
Vue 2 (Options API)
// src/main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import { TraceKitPlugin } from '@tracekit/vue';
import App from './App.vue';
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: () => import('./views/Home.vue') },
{ path: '/dashboard', component: () => import('./views/Dashboard.vue') },
],
});
// Register TraceKit plugin
Vue.use(TraceKitPlugin, {
apiKey: process.env.VUE_APP_TRACEKIT_API_KEY,
serviceName: 'my-vue-app',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
release: process.env.VUE_APP_VERSION || '0.0.0',
environment: process.env.NODE_ENV,
router, // enables automatic route change breadcrumbs
});
new Vue({
router,
render: (h) => h(App),
}).$mount('#app');
Key points:
TraceKitPluginmust be registered beforeapp.mount()(Vue 3) ornew Vue()(Vue 2)- The plugin calls
init()internally — do not callinit()separately - Passing
routeris optional but recommended — it enables automatic navigation breadcrumbs serviceNameshould match your app's logical name
Step 4: Error Handler
The TraceKitPlugin automatically hooks into Vue's error handling lifecycle. It intercepts errors via app.config.errorHandler (Vue 3) or Vue.config.errorHandler (Vue 2) and reports them to TraceKit with component context.
What gets captured automatically:
- Template rendering errors
- Lifecycle hook errors (
mounted,updated, etc.) - Watcher errors
- Component event handler errors (in Vue 3)
Error handler chaining: If you already have a custom errorHandler, the plugin chains with it — your handler runs first, then TraceKit captures the error. No errors are silently swallowed.
// Vue 3 — manual error handler setup (if NOT using the plugin)
import { createApp } from 'vue';
import { setupErrorHandler, captureException } from '@tracekit/vue';
const app = createApp(App);
setupErrorHandler(app); // hooks into app.config.errorHandler
app.mount('#app');
// Vue 2 — manual error handler setup (if NOT using the plugin)
import Vue from 'vue';
import { setupErrorHandler } from '@tracekit/vue';
setupErrorHandler(Vue); // hooks into Vue.config.errorHandler
Capturing errors in event handlers and async code:
For errors outside Vue's error handling lifecycle (e.g., in @click handlers or async methods), use captureException:
Composition API (Vue 3)
<script setup lang="ts">
import { captureException } from '@tracekit/vue';
async function handleSubmit() {
try {
await submitForm();
} catch (err) {
captureException(err as Error, { component: 'ContactForm' });
}
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<!-- form fields -->
<button type="submit">Send</button>
</form>
</template>
Options API (Vue 2)
<script>
export default {
methods: {
async handleSubmit() {
try {
await this.submitForm();
} catch (err) {
this.$tracekit.captureException(err, { component: 'ContactForm' });
}
},
},
};
</script>
<template>
<form @submit.prevent="handleSubmit">
<!-- form fields -->
<button type="submit">Send</button>
</form>
</template>
Step 5: Router Integration
When you pass a router instance to TraceKitPlugin, the plugin automatically captures navigation breadcrumbs. Every route change records:
- Previous route path
- New route path
- Navigation type (push, replace, back/forward)
// Vue 3 — router is passed in plugin options
app.use(TraceKitPlugin, {
apiKey: import.meta.env.VITE_TRACEKIT_API_KEY,
serviceName: 'my-vue-app',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
router, // <-- enables navigation breadcrumbs
});
Manual setup (if not using the plugin):
import { createRouter, createWebHistory } from 'vue-router';
import { setupRouterBreadcrumbs } from '@tracekit/vue';
const router = createRouter({
history: createWebHistory(),
routes: [/* ... */],
});
setupRouterBreadcrumbs(router);
Parameterized routes: By default, route parameters are included in breadcrumbs (e.g., /users/123). To use parameterized paths instead (e.g., /users/:id), pass parameterizedRoutes: true in plugin options.
Step 6: Custom Performance Spans
Composition API (Vue 3)
Use the useTraceKitSpan composable to measure operations within components:
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useTraceKitSpan, captureException } from '@tracekit/vue';
const data = ref(null);
const { startSpan } = useTraceKitSpan();
onMounted(async () => {
const span = startSpan('load-dashboard-data', {
'component': 'Dashboard',
});
try {
const response = await fetch('/api/dashboard');
data.value = await response.json();
span.end();
} catch (err) {
captureException(err as Error);
span.end();
}
});
</script>
Options API (Vue 2)
Use the $tracekit instance property:
<script>
export default {
data() {
return { data: null };
},
async mounted() {
const span = this.$tracekit.startSpan('load-dashboard-data', {
component: 'Dashboard',
});
try {
const response = await fetch('/api/dashboard');
this.data = await response.json();
span.end();
} catch (err) {
this.$tracekit.captureException(err);
span.end();
}
},
};
</script>
Step 7: Distributed Tracing
Configure tracePropagationTargets in the plugin options to attach trace headers to outbound fetch/XHR requests:
app.use(TraceKitPlugin, {
apiKey: import.meta.env.VITE_TRACEKIT_API_KEY,
serviceName: 'my-vue-app',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
tracePropagationTargets: [
'https://api.myapp.com',
'https://auth.myapp.com',
/^https:\/\/.*\.myapp\.com/,
],
router,
});
How it works:
- Fetch/XHR requests to matching URLs receive a
traceparentheader - Your backend SDK reads this header and links the backend span to the frontend trace
- The full request lifecycle appears as a single trace in the TraceKit dashboard
Important: Your backend CORS configuration must accept the traceparent and tracestate headers.
Step 8: Session Replay (Optional)
Enable session replay via the plugin config to record user sessions for visual debugging:
import { replayIntegration } from '@tracekit/replay';
const replay = replayIntegration({
sessionSampleRate: 0.1,
errorSampleRate: 1.0,
maskAllText: true,
blockAllMedia: true,
});
app.use(TraceKitPlugin, {
apiKey: import.meta.env.VITE_TRACEKIT_API_KEY,
serviceName: 'my-vue-app',
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
addons: [replay],
router,
});
Step 9: Source Maps (Optional)
Upload source maps so stack traces show original file names and line numbers.
Add to your .env:
TRACEKIT_AUTH_TOKEN=your_auth_token_here
After building:
tracekit sourcemaps upload --release=1.0.0 ./dist
Build integration — add to package.json:
{
"scripts": {
"build": "vite build",
"postbuild": "tracekit sourcemaps upload --release=$npm_package_version ./dist"
}
}
Ensure the release value matches the release option in your plugin config.
Step 10: Verification
After integrating, verify errors and traces are flowing:
-
Start your application with the API key env var set.
-
Trigger a test error — add this temporarily in a component:
Vue 3:
<script setup lang="ts"> import { onMounted } from 'vue'; import { captureException } from '@tracekit/vue'; onMounted(() => { captureException(new Error('TraceKit Vue test error')); }); </script>Vue 2:
<script> export default { mounted() { this.$tracekit.captureException(new Error('TraceKit Vue test error')); }, }; </script> -
Open
https://app.tracekit.dev/traces. -
Confirm the test error and your service name appear within 30-60 seconds.
-
Remove the test code once verified.
Complete Working Example
Vue 3 (Composition API)
// src/main.ts
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import { TraceKitPlugin } from '@tracekit/vue';
import { replayIntegration } from '@tracekit/replay';
import App from './App.vue';
// --- Routes ---
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: () => import('./views/Home.vue') },
{ path: '/dashboard', component: () => import('./views/Dashboard.vue') },
{ path: '/users/:id', component: () => import('./views/UserProfile.vue') },
],
});
// --- Session Replay ---
const replay = replayIntegration({
sessionSampleRate: 0.1,
errorSampleRate: 1.0,
maskAllText: true,
blockAllMedia: true,
});
// --- App Init ---
const app = createApp(App);
app.use(TraceKitPlugin, {
apiKey: import.meta.env.VITE_TRACEKIT_API_KEY,
serviceName: 'my-vue-app',
release: import.meta.env.VITE_APP_VERSION || '0.0.0',
environment: import.meta.env.MODE,
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
tracePropagationTargets: [
'https://api.myapp.com',
/^https:\/\/.*\.myapp\.com/,
],
addons: [replay],
router,
});
app.use(router);
app.mount('#app');
<!-- src/views/Dashboard.vue -->
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useTraceKitSpan, captureException, setUser, setTag } from '@tracekit/vue';
const data = ref(null);
const error = ref<string | null>(null);
const { startSpan } = useTraceKitSpan();
onMounted(async () => {
// Set user context
setUser({ id: 'user-123', email: 'alice@example.com' });
setTag('plan', 'pro');
// Measure data load
const span = startSpan('load-dashboard');
try {
const response = await fetch('/api/dashboard');
data.value = await response.json();
span.end();
} catch (err) {
captureException(err as Error, { component: 'Dashboard' });
error.value = 'Failed to load dashboard';
span.end();
}
});
</script>
<template>
<div>
<h1>Dashboard</h1>
<div v-if="error" class="error">{{ error }}</div>
<div v-else-if="data">{{ data }}</div>
<div v-else>Loading...</div>
</div>
</template>
Vue 2 (Options API)
// src/main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import { TraceKitPlugin } from '@tracekit/vue';
import App from './App.vue';
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: () => import('./views/Home.vue') },
{ path: '/dashboard', component: () => import('./views/Dashboard.vue') },
{ path: '/users/:id', component: () => import('./views/UserProfile.vue') },
],
});
Vue.use(TraceKitPlugin, {
apiKey: process.env.VUE_APP_TRACEKIT_API_KEY,
serviceName: 'my-vue-app',
release: process.env.VUE_APP_VERSION || '0.0.0',
environment: process.env.NODE_ENV,
endpoint: 'https://app.tracekit.dev/v1/traces',
enableCodeMonitoring: true,
tracePropagationTargets: [
'https://api.myapp.com',
],
router,
});
new Vue({
router,
render: (h) => h(App),
}).$mount('#app');
Troubleshooting
Errors not captured by Vue error handler
- Plugin registration order:
TraceKitPluginmust be registered withapp.use()BEFORE callingapp.mount(). If registered after, the error handler is not installed before the app starts rendering. - Existing error handler: If you have a custom
app.config.errorHandler, the plugin chains with it. Ensure your handler does not swallow errors silently. - Async errors: Errors in
asyncmethods called from@clickhandlers are NOT caught by Vue'serrorHandlerin Vue 2. Usetry/catchwithcaptureException. Vue 3 catches these automatically.
Vue 2 vs Vue 3 init differences
| Feature | Vue 2 | Vue 3 |
|---|---|---|
| Plugin registration | Vue.use(TraceKitPlugin, opts) | app.use(TraceKitPlugin, opts) |
| Error handler | Vue.config.errorHandler | app.config.errorHandler |
| Instance access | this.$tracekit | useTraceKitSpan() composable |
| Router | new VueRouter() | createRouter() |
| Env vars | VUE_APP_* (Webpack) | VITE_* (Vite) |
Router events not tracking
- Check router is passed to plugin: Navigation breadcrumbs only work when
routeris included in plugin options. - Check router version: Vue Router 3.x for Vue 2, Vue Router 4.x for Vue 3. Mismatched versions cause silent failures.
- Manual setup: If not using the plugin, call
setupRouterBreadcrumbs(router)after creating the router.
Distributed tracing not connecting
- Check
tracePropagationTargets: URLs must match your backend endpoints. Verifytraceparentheaders appear in the browser Network tab. - Check CORS: Your backend must accept
traceparentandtracestateinAccess-Control-Allow-Headers. - Check backend SDK: The backend must be instrumented with a TraceKit SDK that reads
traceparent.
Source maps not resolving
- Check release version: The
releasein plugin config must match the--releaseflag during upload. - Vue CLI output: Upload from
./dist. - Vite output: Upload from
./dist.
Next Steps
Once your Vue app is traced, consider:
- Code Monitoring — Set live breakpoints and capture snapshots in production without redeploying (already enabled via
enableCodeMonitoring: true) - Session Replay — Visual debugging with full session recordings (see
tracekit-session-replayskill) - Source Maps — Readable stack traces with original source code (see
tracekit-source-mapsskill) - Backend Tracing — Add
@tracekit/node-apmor another backend SDK for end-to-end distributed traces (seetracekit-node-sdk,tracekit-go-sdk, and other backend skills) - Browser SDK — For advanced browser-level configuration, see the
tracekit-browser-sdkskill
References
- Vue SDK docs:
https://app.tracekit.dev/docs/frontend/frameworks/vue - TraceKit docs root:
https://app.tracekit.dev/docs - Dashboard:
https://app.tracekit.dev - Quick start:
https://app.tracekit.dev/docs/quickstart