Vue Integration
Track your Vue.js application with Ovyxa, including Vue Router integration and custom event tracking.
Installation
Add Tracking Script
Add Ovyxa to your public/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Vue App</title>
<!-- Ovyxa Analytics -->
<script async src="https://ingest.ovyxa.com/js/script.js" data-domain="YOUR_DOMAIN"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
Vue Router Integration
Track route changes automatically with Vue Router.
Vue 3 + Vue Router 4
// src/main.js
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './App.vue'
const router = createRouter({
history: createWebHistory(),
routes: [
// your routes
]
})
// Track route changes
router.afterEach((to) => {
if (window.ovyxa) {
window.ovyxa('pageview', {
url: to.fullPath
})
}
})
const app = createApp(App)
app.use(router)
app.mount('#app')
Vue 2 + Vue Router 3
// src/main.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
routes: [
// your routes
]
})
// Track route changes
router.afterEach((to) => {
if (window.ovyxa) {
window.ovyxa('pageview', {
url: to.fullPath
})
}
})
new Vue({
router,
render: h => h(App)
}).$mount('#app')
Custom Events
Track user interactions throughout your Vue app.
Component Methods
<template>
<button @click="handleSignup">Sign Up</button>
</template>
<script>
export default {
methods: {
handleSignup() {
// Track event
window.ovyxa('event', 'SignupClick', {
location: 'homepage',
plan: 'free'
})
// Your signup logic...
}
}
}
</script>
Composition API (Vue 3)
<template>
<button @click="handleClick">Track Me</button>
</template>
<script setup>
const handleClick = () => {
window.ovyxa('event', 'ButtonClick', {
button: 'cta',
page: 'home'
})
}
</script>
Vue Plugin
Create a Vue plugin for cleaner integration:
Vue 3 Plugin
// src/plugins/analytics.js
export default {
install: (app, options) => {
app.config.globalProperties.$ovyxa = {
event: (name, properties) => {
if (window.ovyxa) {
window.ovyxa('event', name, properties)
}
},
pageview: (url) => {
if (window.ovyxa) {
window.ovyxa('pageview', { url })
}
}
}
}
}
// src/main.js
import analytics from './plugins/analytics'
const app = createApp(App)
app.use(analytics)
app.mount('#app')
// Usage in components
export default {
methods: {
trackAction() {
this.$ovyxa.event('Action', { type: 'click' })
}
}
}
Vue 2 Plugin
// src/plugins/analytics.js
export default {
install(Vue) {
Vue.prototype.$ovyxa = {
event(name, properties) {
if (window.ovyxa) {
window.ovyxa('event', name, properties)
}
},
pageview(url) {
if (window.ovyxa) {
window.ovyxa('pageview', { url })
}
}
}
}
}
// src/main.js
import analytics from './plugins/analytics'
Vue.use(analytics)
// Usage
this.$ovyxa.event('Purchase', { amount: 99.99 })
Composable (Vue 3)
Create a reusable composable:
// src/composables/useTracking.js
export function useTracking() {
const trackEvent = (eventName, properties = {}) => {
if (window.ovyxa) {
window.ovyxa('event', eventName, properties)
}
}
const trackPageView = (url) => {
if (window.ovyxa) {
window.ovyxa('pageview', { url })
}
}
return {
trackEvent,
trackPageView
}
}
// Usage in components
<script setup>
import { useTracking } from '@/composables/useTracking'
const { trackEvent } = useTracking()
const handleClick = () => {
trackEvent('ButtonClick', { button: 'signup' })
}
</script>
TypeScript Support
Type-safe tracking with TypeScript:
// src/types/analytics.ts
declare global {
interface Window {
ovyxa: (
action: 'event' | 'pageview',
name: string,
properties?: Record<string, any>
) => void
}
}
export interface EventProperties {
[key: string]: string | number | boolean
}
// src/composables/useTracking.ts
import type { EventProperties } from '@/types/analytics'
export function useTracking() {
const trackEvent = (
eventName: string,
properties?: EventProperties
): void => {
window.ovyxa?.('event', eventName, properties)
}
return { trackEvent }
}
E-commerce Tracking
Track purchases and cart events:
<template>
<div>
<button @click="addToCart">Add to Cart</button>
<button @click="checkout">Checkout</button>
</div>
</template>
<script setup>
import { useTracking } from '@/composables/useTracking'
const { trackEvent } = useTracking()
const product = {
id: 'prod_123',
name: 'Widget',
price: 29.99
}
const addToCart = () => {
trackEvent('AddToCart', {
productId: product.id,
productName: product.name,
price: product.price
})
// Add to cart logic...
}
const checkout = () => {
trackEvent('Purchase', {
revenue: 29.99,
currency: 'USD',
productId: product.id
})
// Checkout logic...
}
</script>
Form Tracking
<template>
<form @submit.prevent="handleSubmit">
<input v-model="email" type="email" />
<button type="submit">Subscribe</button>
</form>
</template>
<script setup>
import { ref } from 'vue'
import { useTracking } from '@/composables/useTracking'
const email = ref('')
const { trackEvent } = useTracking()
const handleSubmit = () => {
trackEvent('NewsletterSignup', {
source: 'footer',
page: window.location.pathname
})
// Submit form...
}
</script>
Nuxt.js Integration
For Nuxt 3:
Create Plugin
// plugins/analytics.client.js
export default defineNuxtPlugin((nuxtApp) => {
// Add script to head
useHead({
script: [
{
src: 'https://ingest.ovyxa.com/js/script.js',
'data-site': 'YOUR_DOMAIN',
async: true
}
]
})
// Track route changes
const router = useRouter()
router.afterEach((to) => {
if (window.ovyxa) {
window.ovyxa('pageview', {
url: to.fullPath
})
}
})
// Provide tracking methods
return {
provide: {
ovyxa: {
event: (name, properties) => {
if (window.ovyxa) {
window.ovyxa('event', name, properties)
}
}
}
}
}
})
// Usage in pages
<script setup>
const { $ovyxa } = useNuxtApp()
const trackClick = () => {
$ovyxa.event('Click', { button: 'hero-cta' })
}
</script>
Vite
Works out of the box with Vite. Just add script to index.html.
Environment Variables
// vite.config.js
export default {
define: {
__OVYXA_SITE_ID__: JSON.stringify(
process.env.VITE_OVYXA_SITE_ID
)
}
}
// .env.production
VITE_OVYXA_SITE_ID=your_site_id
// .env.development
VITE_OVYXA_SITE_ID=dev_site_id
Testing
Mock analytics in tests:
// tests/setup.js
global.window.ovyxa = vi.fn()
// Component.spec.js
import { mount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'
describe('MyComponent', () => {
it('tracks event on click', async () => {
const wrapper = mount(MyComponent)
await wrapper.find('button').trigger('click')
expect(window.ovyxa).toHaveBeenCalledWith(
'event',
'ButtonClick',
{ button: 'cta' }
)
})
})
Conditional Tracking
Only track in production:
// src/composables/useTracking.js
export function useTracking() {
const isProduction = import.meta.env.PROD
const trackEvent = (eventName, properties) => {
if (isProduction && window.ovyxa) {
window.ovyxa('event', eventName, properties)
}
}
return { trackEvent }
}
Troubleshooting
Events Not Tracking
Check if script loaded:
console.log(typeof window.ovyxa) // Should be 'function'
Route Changes Not Tracked
Verify router.afterEach hook is set up in main.js.
Nuxt SSR Issues
Use .client.js suffix for client-only plugins to avoid SSR errors.
Best Practices
- Use a composable - Cleaner component code
- Create a plugin - Global access via
this.$ovyxa - Type your events - Use TypeScript for safety
- Test tracking - Mock window.ovyxa
- Environment-based - Only track in production
Example Apps
- Vue 3: github.com/ovyxa/examples/vue3
- Nuxt 3: github.com/ovyxa/examples/nuxt3
Next Steps
Questions? Email support@ovyxa.com