S
Integrations/Vue / Nuxt

🟢 Vue / Nuxt Integration

Integrate Sypnia with Vue 3 or Nuxt 3 applications.

🌟 Vue 3 Setup

1. Add the Script

Add the SDK to your index.html:

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Vue App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
    <script src="https://sypnia.com/api/sdk/YOUR_PROJECT_KEY"></script>
  </body>
</html>

2. Create Composable

Create a composable for analytics:

src/composables/useAnalytics.ts
declare global {
  interface Window {
    Sypnia: {
      track: (event: string, props?: Record<string, unknown>) => void;
      identify: (userId: string, traits?: Record<string, unknown>) => void;
      page: () => void;
      feedback: (score: number | null, message?: string) => void;
    };
  }
}

export function useAnalytics() {
  const track = (event: string, properties?: Record<string, unknown>) => {
    window.Sypnia?.track(event, properties);
  };

  const identify = (userId: string, traits?: Record<string, unknown>) => {
    window.Sypnia?.identify(userId, traits);
  };

  const page = () => {
    window.Sypnia?.page();
  };

  const feedback = (score: number | null, message?: string) => {
    window.Sypnia?.feedback(score, message);
  };

  return { track, identify, page, feedback };
}

3. Router Integration

Track page views with Vue Router:

src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router';

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

// Track page views
router.afterEach(() => {
  window.Sypnia?.page();
});

export default router;

📝 Usage in Components

src/components/ProductCard.vue
<script setup lang="ts">
import { useAnalytics } from '@/composables/useAnalytics';

const props = defineProps<{
  product: {
    id: string;
    name: string;
    price: number;
  };
}>();

const { track } = useAnalytics();

const addToCart = () => {
  track('add_to_cart', {
    product_id: props.product.id,
    product_name: props.product.name,
    price: props.product.price
  });
  // Add to cart logic...
};
</script>

<template>
  <div class="product-card">
    <h3>{{ product.name }}</h3>
    <p>${{ product.price }}</p>
    <button @click="addToCart">Add to Cart</button>
  </div>
</template>

💚 Nuxt 3 Setup

1. Create Plugin

Create a Nuxt plugin to load the SDK:

plugins/sypnia.client.ts
export default defineNuxtPlugin(() => {
  // Only run on client
  if (process.server) return;

  // Load the SDK script
  const script = document.createElement('script');
  script.src = 'https://sypnia.com/api/sdk/YOUR_PROJECT_KEY';
  script.async = true;
  document.body.appendChild(script);

  // Track page views on route change
  const router = useRouter();
  router.afterEach(() => {
    // Small delay to ensure SDK is ready
    setTimeout(() => {
      window.Sypnia?.page();
    }, 0);
  });
});

2. Create Composable

composables/useAnalytics.ts
declare global {
  interface Window {
    Sypnia: {
      track: (event: string, props?: Record<string, unknown>) => void;
      identify: (userId: string, traits?: Record<string, unknown>) => void;
      page: () => void;
      feedback: (score: number | null, message?: string) => void;
    };
  }
}

export const useAnalytics = () => {
  const track = (event: string, properties?: Record<string, unknown>) => {
    if (process.client) {
      window.Sypnia?.track(event, properties);
    }
  };

  const identify = (userId: string, traits?: Record<string, unknown>) => {
    if (process.client) {
      window.Sypnia?.identify(userId, traits);
    }
  };

  const page = () => {
    if (process.client) {
      window.Sypnia?.page();
    }
  };

  const feedback = (score: number | null, message?: string) => {
    if (process.client) {
      window.Sypnia?.feedback(score, message);
    }
  };

  return { track, identify, page, feedback };
};

3. Usage in Pages

pages/checkout.vue
<script setup lang="ts">
const { track, identify } = useAnalytics();

// Track when user completes checkout
const completeCheckout = async () => {
  try {
    const order = await processOrder();
    
    track('purchase', {
      order_id: order.id,
      value: order.total,
      currency: 'USD',
      items: order.items.length
    });
    
    navigateTo('/thank-you');
  } catch (error) {
    track('checkout_error', {
      error: error.message
    });
  }
};

// Identify user from auth
const { data: user } = useAuth();
if (user.value) {
  identify(user.value.id, {
    email: user.value.email,
    name: user.value.name
  });
}
</script>

<template>
  <div>
    <h1>Checkout</h1>
    <button @click="completeCheckout">Complete Order</button>
  </div>
</template>

🔧 Vue Plugin (Optional)

For Vue 3 apps, you can create a plugin for global access:

src/plugins/analytics.ts
import type { App } from 'vue';

export const analyticsPlugin = {
  install(app: App) {
    app.config.globalProperties.$analytics = {
      track: (event: string, properties?: Record<string, unknown>) => {
        window.Sypnia?.track(event, properties);
      },
      identify: (userId: string, traits?: Record<string, unknown>) => {
        window.Sypnia?.identify(userId, traits);
      },
      page: () => {
        window.Sypnia?.page();
      }
    };

    // Also provide for Composition API
    app.provide('analytics', app.config.globalProperties.$analytics);
  }
};

// In main.ts
import { createApp } from 'vue';
import { analyticsPlugin } from './plugins/analytics';

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

🎯 Pinia Store Integration

Track state changes with Pinia:

src/stores/cart.ts
import { defineStore } from 'pinia';
import { useAnalytics } from '@/composables/useAnalytics';

export const useCartStore = defineStore('cart', () => {
  const items = ref<CartItem[]>([]);
  const { track } = useAnalytics();

  function addItem(product: Product) {
    items.value.push({
      id: product.id,
      name: product.name,
      price: product.price,
      quantity: 1
    });
    
    track('add_to_cart', {
      product_id: product.id,
      product_name: product.name,
      price: product.price,
      cart_size: items.value.length
    });
  }

  function removeItem(productId: string) {
    const item = items.value.find(i => i.id === productId);
    items.value = items.value.filter(i => i.id !== productId);
    
    if (item) {
      track('remove_from_cart', {
        product_id: item.id,
        product_name: item.name
      });
    }
  }

  return { items, addItem, removeItem };
});
💡 SSR Note: The Sypnia SDK only runs on the client side. Always wrap analytics calls in client-side checks when using Nuxt's SSR features.