Skip to main content

Installation

npm install @databuddy/sdk
Requires Vue 3.0 or higher.

Databuddy Component

The <Databuddy /> component injects the tracking script into your Vue app.

Setup

Register the component globally:
src/main.ts
import { createApp } from 'vue';
import { Databuddy } from '@databuddy/sdk/vue';
import App from './App.vue';

const app = createApp(App);

app.component('Databuddy', Databuddy);
app.mount('#app');

Usage in Root Component

App.vue
<template>
  <div id="app">
    <RouterView />
    
    <Databuddy
      client-id="your-client-id"
      :track-web-vitals="true"
      :track-errors="true"
      :track-scroll-depth="true"
    />
  </div>
</template>
Prop names use kebab-case in templates: client-id, track-web-vitals, etc.

Component Props

All configuration options are available as props:
<template>
  <Databuddy
    client-id="your-client-id"
    api-url="https://basket.databuddy.cc"
    
    :track-web-vitals="true"
    :track-errors="true"
    :track-scroll-depth="true"
    :track-outgoing-links="true"
    :track-interactions="true"
    :track-attributes="true"
    
    :sampling-rate="0.5"
    :enable-batching="true"
    :batch-size="10"
    :batch-timeout="2000"
    
    :disabled="!userConsent"
    :skip-patterns="['/admin/**']"
    :mask-patterns="['/users/*']"
    
    :debug="isDevelopment"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const userConsent = ref(true);
const isDevelopment = import.meta.env.DEV;
</script>

Tracking Functions

Import tracking functions from the core SDK:
import { track, flush, clear } from '@databuddy/sdk';

Track Custom Events

<template>
  <button @click="handleCheckout">Checkout</button>
</template>

<script setup lang="ts">
import { track } from '@databuddy/sdk';

const handleCheckout = () => {
  track('checkout_started', {
    cartValue: 99.99,
    itemCount: 3,
    currency: 'USD'
  });
};
</script>

Track Page Views

<template>
  <div>Pricing page content...</div>
</template>

<script setup lang="ts">
import { track } from '@databuddy/sdk';
import { onMounted } from 'vue';

onMounted(() => {
  track('pricing_page_viewed', {
    source: 'navigation',
    timestamp: Date.now()
  });
});
</script>

Track Form Submissions

<template>
  <form @submit.prevent="handleSubmit">
    <input v-model="email" type="email" placeholder="Email" />
    <button type="submit">Subscribe</button>
  </form>
</template>

<script setup lang="ts">
import { track } from '@databuddy/sdk';
import { ref } from 'vue';

const email = ref('');

const handleSubmit = () => {
  track('signup_form_submitted', {
    formType: 'newsletter',
    source: 'footer'
  });
  
  // Submit form...
};
</script>

Track Errors

<script setup lang="ts">
import { trackError } from '@databuddy/sdk';
import { onMounted } from 'vue';

onMounted(async () => {
  try {
    const res = await fetch('/api/data');
    if (!res.ok) throw new Error('Fetch failed');
  } catch (error) {
    trackError(error.message, {
      error_type: error.name,
      context: 'data_fetcher',
      endpoint: '/api/data'
    });
  }
});
</script>

Session Management

Get Tracking IDs

<template>
  <div>
    <p>Anonymous ID: {{ anonId }}</p>
    <p>Session ID: {{ sessionId }}</p>
  </div>
</template>

<script setup lang="ts">
import { getAnonymousId, getSessionId } from '@databuddy/sdk';
import { ref, onMounted } from 'vue';

const anonId = ref<string | null>(null);
const sessionId = ref<string | null>(null);

onMounted(() => {
  anonId.value = getAnonymousId();
  sessionId.value = getSessionId();
});
</script>

Clear Session on Logout

<template>
  <button @click="handleLogout">Logout</button>
</template>

<script setup lang="ts">
import { clear } from '@databuddy/sdk';
import { useRouter } from 'vue-router';

const router = useRouter();

const handleLogout = async () => {
  // Clear tracking session
  clear();
  
  // Clear auth session
  await fetch('/api/logout', { method: 'POST' });
  
  router.push('/login');
};
</script>
<template>
  <a :href="externalUrl">Visit Shop</a>
</template>

<script setup lang="ts">
import { getTrackingParams } from '@databuddy/sdk';
import { computed } from 'vue';

const externalUrl = computed(() => {
  const params = getTrackingParams();
  return `https://shop.example.com${params ? `?${params}` : ''}`;
});
</script>

Feature Flags

FlagsPlugin Setup

src/main.ts
import { createApp } from 'vue';
import { createFlagsPlugin } from '@databuddy/sdk/vue';
import App from './App.vue';

const app = createApp(App);

const flagsPlugin = createFlagsPlugin({
  clientId: 'your-client-id',
  user: {
    userId: '12345',
    email: '[email protected]'
  }
});

app.use(flagsPlugin);
app.mount('#app');

useFlag Composable

Get a feature flag’s full state:
<template>
  <div v-if="flag.loading">
    <Skeleton />
  </div>
  <div v-else-if="flag.on">
    <NewCheckout :variant="flag.state.variant" />
  </div>
  <div v-else>
    <OldCheckout />
  </div>
</template>

<script setup lang="ts">
import { useFlag } from '@databuddy/sdk/vue';

const flag = useFlag('new-checkout-flow');
</script>

useBooleanFlag Composable

Simple boolean check:
<template>
  <div :class="darkMode ? 'dark' : 'light'">
    <!-- Content -->
  </div>
</template>

<script setup lang="ts">
import { useBooleanFlag } from '@databuddy/sdk/vue';

const darkMode = useBooleanFlag('dark-mode');
</script>

useFlags Composable

Access the full flags context:
<template>
  <div>
    <button @click="handleRefresh">Refresh Flags</button>
    <p>Flags ready: {{ flags.isReady }}</p>
  </div>
</template>

<script setup lang="ts">
import { useFlags } from '@databuddy/sdk/vue';

const flags = useFlags();

const handleRefresh = async () => {
  await flags.refresh();
};
</script>

Composable Patterns

Custom Analytics Composable

Create reusable tracking logic:
composables/useAnalytics.ts
import { track } from '@databuddy/sdk';
import { onMounted, onUnmounted } from 'vue';

export function usePageTracking(pageName: string) {
  const startTime = Date.now();
  
  onMounted(() => {
    track('page_view', {
      pageName,
      timestamp: startTime
    });
  });
  
  onUnmounted(() => {
    const timeOnPage = Date.now() - startTime;
    track('page_exit', {
      pageName,
      timeOnPage
    });
  });
}

// Usage in component
import { usePageTracking } from '@/composables/useAnalytics';

usePageTracking('pricing-page');

Event Tracking Composable

composables/useEventTracking.ts
import { track } from '@databuddy/sdk';
import type { EventProperties } from '@databuddy/sdk';

export function useEventTracking() {
  const trackClick = (element: string, properties?: EventProperties) => {
    track('element_clicked', {
      element,
      ...properties
    });
  };
  
  const trackConversion = (type: string, value: number) => {
    track('conversion', {
      type,
      value,
      currency: 'USD'
    });
  };
  
  return {
    trackClick,
    trackConversion
  };
}
Usage:
<template>
  <button @click="trackClick('cta_button', { location: 'hero' })">
    Get Started
  </button>
</template>

<script setup lang="ts">
import { useEventTracking } from '@/composables/useEventTracking';

const { trackClick } = useEventTracking();
</script>

Router Integration

Track route changes automatically:
src/main.ts
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import { track } from '@databuddy/sdk';
import App from './App.vue';

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

// Track page views on navigation
router.afterEach((to, from) => {
  track('page_view', {
    path: to.path,
    name: to.name,
    fromPath: from.path
  });
});

const app = createApp(App);
app.use(router);
app.mount('#app');

Advanced Usage

Conditional Rendering

<template>
  <div id="app">
    <RouterView />
    
    <Databuddy
      v-if="shouldTrack"
      client-id="your-client-id"
      :track-web-vitals="true"
    />
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue';

const isDevelopment = import.meta.env.DEV;
const userConsent = ref(true);

const shouldTrack = computed(() => {
  return !isDevelopment && userConsent.value;
});
</script>

Reactive Configuration

<template>
  <Databuddy
    v-if="config"
    :client-id="config.clientId"
    :track-web-vitals="config.trackWebVitals"
    :debug="config.debug"
  />
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';

const config = ref(null);

onMounted(async () => {
  const res = await fetch('/api/analytics-config');
  config.value = await res.json();
});
</script>

Flush Before Navigation

<template>
  <button @click="handleExternalLink">Visit External Site</button>
</template>

<script setup lang="ts">
import { track, flush } from '@databuddy/sdk';

const handleExternalLink = () => {
  const url = 'https://example.com';
  
  track('external_link_clicked', { url });
  
  // Ensure event is sent before leaving
  flush();
  
  setTimeout(() => {
    window.location.href = url;
  }, 100);
};
</script>

TypeScript Support

Full TypeScript support with type inference:
<script setup lang="ts">
import type { DatabuddyConfig, EventProperties } from '@databuddy/sdk';
import { track } from '@databuddy/sdk';
import { ref } from 'vue';

const config: DatabuddyConfig = {
  clientId: 'your-client-id',
  trackWebVitals: true,
  samplingRate: 0.5,
};

// Type-safe event properties
const trackPurchase = (price: number, currency: string) => {
  const properties: EventProperties = {
    price,
    currency,
    timestamp: Date.now()
  };
  
  track('purchase_completed', properties);
};
</script>

Next Steps

Configuration

See all available configuration options

React SDK

React hooks and components

JavaScript SDK

Vanilla JavaScript usage

Node.js SDK

Server-side event tracking

Build docs developers (and LLMs) love