diff --git a/apps/public/content/guides/nuxt-analytics.mdx b/apps/public/content/guides/nuxt-analytics.mdx new file mode 100644 index 00000000..3d416f5f --- /dev/null +++ b/apps/public/content/guides/nuxt-analytics.mdx @@ -0,0 +1,354 @@ +--- +title: "How to add analytics to Nuxt" +description: "Add privacy-first analytics to your Nuxt app in under 5 minutes with OpenPanel's official Nuxt module." +difficulty: beginner +timeToComplete: 5 +date: 2025-01-07 +cover: /content/cover-default.jpg +team: OpenPanel Team +steps: + - name: "Install the module" + anchor: "install" + - name: "Configure the module" + anchor: "setup" + - name: "Track custom events" + anchor: "events" + - name: "Identify users" + anchor: "identify" + - name: "Set up server-side tracking" + anchor: "server" + - name: "Verify your setup" + anchor: "verify" +--- + +# How to add analytics to Nuxt + +This guide walks you through adding OpenPanel to a Nuxt 3 application. The official `@openpanel/nuxt` module makes integration effortless with auto-imported composables, automatic page view tracking, and a built-in proxy option to bypass ad blockers. + +OpenPanel is an open-source alternative to Mixpanel and Google Analytics. It uses cookieless tracking by default, so you won't need cookie consent banners for basic analytics. + +## Prerequisites + +- A Nuxt 3 project +- An OpenPanel account ([sign up free](https://dashboard.openpanel.dev/onboarding)) +- Your Client ID from the OpenPanel dashboard + +## Install the module [#install] + +Start by installing the OpenPanel Nuxt module. This package includes everything you need for client-side tracking, including the auto-imported `useOpenPanel` composable. + +```bash +npm install @openpanel/nuxt +``` + +If you prefer pnpm or yarn, those work too. + +## Configure the module [#setup] + +Add the module to your `nuxt.config.ts` and configure it with your Client ID. The module automatically sets up page view tracking and makes the `useOpenPanel` composable available throughout your app. + +```ts title="nuxt.config.ts" +export default defineNuxtConfig({ + modules: ['@openpanel/nuxt'], + openpanel: { + clientId: 'your-client-id', + trackScreenViews: true, + trackOutgoingLinks: true, + trackAttributes: true, + }, +}); +``` + +That's it. Page views are now being tracked automatically as users navigate your app. + +### Configuration options + +| Option | Default | Description | +|--------|---------|-------------| +| `clientId` | — | Your OpenPanel client ID (required) | +| `apiUrl` | `https://api.openpanel.dev` | The API URL to send events to | +| `trackScreenViews` | `true` | Automatically track page views | +| `trackOutgoingLinks` | `true` | Track clicks on external links | +| `trackAttributes` | `true` | Track elements with `data-track` attributes | +| `trackHashChanges` | `false` | Track hash changes in URL | +| `disabled` | `false` | Disable all tracking | +| `proxy` | `false` | Route events through your server | + +### Using environment variables + +For production applications, store your Client ID in environment variables. + +```ts title="nuxt.config.ts" +export default defineNuxtConfig({ + modules: ['@openpanel/nuxt'], + openpanel: { + clientId: process.env.NUXT_PUBLIC_OPENPANEL_CLIENT_ID, + trackScreenViews: true, + }, +}); +``` + +```bash title=".env" +NUXT_PUBLIC_OPENPANEL_CLIENT_ID=your-client-id +``` + +## Track custom events [#events] + +Page views only tell part of the story. To understand how users interact with your product, track custom events like button clicks, form submissions, or feature usage. + +### Using the composable + +The `useOpenPanel` composable is auto-imported, so you can use it directly in any component without importing anything. + +```vue title="components/SignupButton.vue" + + + +``` + +### Accessing via useNuxtApp + +You can also access the OpenPanel instance through `useNuxtApp()` if you prefer. + +```vue + +``` + +### Track form submissions + +Form tracking helps you understand conversion rates and identify where users drop off. + +```vue title="components/ContactForm.vue" + + + +``` + +### Use data attributes for declarative tracking + +The SDK supports declarative tracking using `data-track` attributes. This is useful for simple click tracking without writing JavaScript. + +```vue + +``` + +When a user clicks this button, OpenPanel automatically sends a `button_clicked` event with the specified properties. This requires `trackAttributes: true` in your configuration. + +## Identify users [#identify] + +Anonymous tracking is useful, but identifying users unlocks more valuable insights. You can track behavior across sessions, segment users by properties, and build cohort analyses. + +Call `identify` after a user logs in or when you have their information available. + +```vue title="components/UserProfile.vue" + + + +``` + +### Set global properties + +Properties set with `setGlobalProperties` are included with every event. This is useful for app version tracking, feature flags, or A/B test variants. + +```vue title="app.vue" + +``` + +### Clear user data on logout + +When users log out, clear the stored profile data to ensure subsequent events aren't associated with the previous user. + +```vue title="components/LogoutButton.vue" + + + +``` + +## Set up server-side tracking [#server] + +For tracking events in server routes, API endpoints, or server middleware, use the `@openpanel/sdk` package. Server-side tracking requires a client secret for authentication. + +### Install the SDK + +```bash +npm install @openpanel/sdk +``` + +### Create a server instance + +```ts title="server/utils/op.ts" +import { OpenPanel } from '@openpanel/sdk'; + +export const op = new OpenPanel({ + clientId: process.env.OPENPANEL_CLIENT_ID!, + clientSecret: process.env.OPENPANEL_CLIENT_SECRET!, +}); +``` + +### Track events in server routes + +```ts title="server/api/webhook.post.ts" +export default defineEventHandler(async (event) => { + const body = await readBody(event); + + await op.track('webhook_received', { + source: body.source, + event_type: body.type, + }); + + return { success: true }; +}); +``` + +Never expose your client secret on the client side. Keep it in server-only code. + +### Awaiting in serverless environments + +If you're deploying to a serverless platform like Vercel or Netlify, make sure to await the tracking call to ensure it completes before the function terminates. + +```ts +export default defineEventHandler(async (event) => { + // Always await in serverless environments + await op.track('my_server_event', { foo: 'bar' }); + return { message: 'Event logged!' }; +}); +``` + +## Bypass ad blockers with proxy [#proxy] + +Many ad blockers block requests to third-party analytics domains. The Nuxt module includes a built-in proxy that routes events through your own server. + +Enable the proxy option in your configuration: + +```ts title="nuxt.config.ts" +export default defineNuxtConfig({ + modules: ['@openpanel/nuxt'], + openpanel: { + clientId: 'your-client-id', + proxy: true, // Routes events through /api/openpanel/* + }, +}); +``` + +When `proxy: true` is set: +- The module automatically sets `apiUrl` to `/api/openpanel` +- A server handler is registered at `/api/openpanel/**` +- All tracking requests route through your Nuxt server + +This makes tracking requests invisible to browser extensions that block third-party analytics. + +## Verify your setup [#verify] + +Open your Nuxt app in the browser and navigate between a few pages. Interact with elements that trigger custom events. Then open your [OpenPanel dashboard](https://dashboard.openpanel.dev) and check the Real-time view to see events appearing within seconds. + +If events aren't showing up, check the browser console for errors. The most common issues are: +- Incorrect client ID +- Ad blockers intercepting requests (enable the proxy option) +- Client ID exposed in server-only code + +The Network tab in your browser's developer tools can help you confirm that requests are being sent. + +## Next steps + +The [Nuxt SDK reference](/docs/sdks/nuxt) covers additional features like incrementing user properties and event filtering. If you're interested in understanding how OpenPanel handles privacy, read our article on [cookieless analytics](/articles/cookieless-analytics). + + + +Yes. The `@openpanel/nuxt` module supports both Nuxt 3 and Nuxt 4. It uses Nuxt's module system and auto-imports, so everything works seamlessly with either version. + + + +Yes. The module automatically registers the `useOpenPanel` composable, so you can use it in any component without importing it. You can also access the instance via `useNuxtApp().$openpanel`. + + + +No. OpenPanel uses cookieless tracking by default. This means you don't need cookie consent banners for basic analytics under most privacy regulations, including GDPR and PECR. + + + +Enable the `proxy: true` option in your configuration. This routes all tracking requests through your Nuxt server at `/api/openpanel/*`, which ad blockers don't typically block. + + + +Yes. OpenPanel is designed for GDPR compliance with cookieless tracking, data minimization, and full support for data subject rights. With self-hosting, you also eliminate international data transfer concerns entirely. + + +