This guide shows you how to add Pieowl to a Nuxt app. One script tag in nuxt.config.ts gives you automatic page views, including client-side navigation. @pieowl/bots adds AI crawler tracking and a proxy to get around ad blockers.
The tracker never sets a cookie, so in many cases you don't need a consent banner for your analytics. See when you still do.
Prerequisites
- A Nuxt 3 or Nuxt 4 project
- A Pieowl account (start a 14-day free trial)
- Your Client ID from the Pieowl dashboard
Get your snippet
There is no package to install for the browser. Pieowl is one script tag, loaded from pieowl.com. The snippet has two parts. The first line creates a small queue, so calls made before pieowl.js loads (for example in onMounted) are sent once it's ready. The second loads the script with your Client ID.
Add the script
Add both scripts to app.head in nuxt.config.ts, so they load on every page.
const pieowlQueue = `window.pieowl=window.pieowl||function(){(window.pieowl.q=window.pieowl.q||[]).push(arguments)};`;
export default defineNuxtConfig({
app: {
head: {
script: [
{ innerHTML: pieowlQueue },
{ src: 'https://pieowl.com/pieowl.js', 'data-client-id': 'your-client-id', defer: true },
],
},
},
});That's it. Page views are now tracked as users move through your app.
What gets collected
What the script collects by itself is set in Settings → Site → What Pieowl counts: page views, clicks on links to other sites, clicks on elements with data-track, address changes after #, and session replay. A change reaches your site within about a minute, with no code to edit.
Configuration options
Options that need code go in an init call. To use them, switch to the init form.
| Option | Default | Description |
|---|---|---|
clientId | — | Your Pieowl client ID (required) |
apiUrl | https://api.pieowl.com | Where events are sent |
disabled | false | Hold all events until you call ready() |
Using environment variables
In production, keep your Client ID in an environment variable. nuxt.config.ts reads it when the app is built.
{ src: 'https://pieowl.com/pieowl.js', 'data-client-id': process.env.NUXT_PUBLIC_PIEOWL_CLIENT_ID, defer: true },NUXT_PUBLIC_PIEOWL_CLIENT_ID=your-client-idTrack custom events
Page views are only part of the story. To see how people use your product, track custom events such as button clicks, form submits or feature use.
Calling window.pieowl
Call window.pieowl('track') from any component. Call it in event handlers or onMounted, not at the top of <script setup>: there is no window during server rendering.
<script setup>
function handleClick() {
window.pieowl('track', 'button_clicked', {
button_name: 'signup',
button_location: 'hero',
});
}
</script>
<template>
<button type="button" @click="handleClick">Sign Up</button>
</template>TypeScript
With TypeScript, declare window.pieowl once, in any .d.ts file.
declare global {
interface Window {
pieowl: (method: string, ...args: any[]) => void;
}
}
export {};Track form submissions
Form tracking helps you see conversion rates and where users drop off.
<script setup>
const email = ref('');
async function handleSubmit() {
window.pieowl('track', 'form_submitted', {
form_name: 'contact',
form_location: 'homepage',
});
// Your form submission logic
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<input v-model="email" type="email" placeholder="Enter your email" />
<button type="submit">Submit</button>
</form>
</template>Use data attributes for declarative tracking
You can also track clicks with data-track attributes, without writing JavaScript.
<template>
<button
data-track="button_clicked"
data-button-name="signup"
data-button-location="hero"
>
Sign Up
</button>
</template>When someone clicks this button, Pieowl sends a button_clicked event. The other data-* attributes become properties in camelCase: buttonName and buttonLocation. This needs Clicks you marked in your code to be on in Settings → Site (it is by default).
Identify users
Anonymous data is useful. Knowing who did what is more useful. When you identify users, you can follow them across sessions, filter by their properties and build cohorts.
Call identify after a user logs in.
<script setup>
const props = defineProps(['user']);
watch(() => props.user, (user) => {
if (user && import.meta.client) {
window.pieowl('identify', {
profileId: user.id,
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
properties: {
plan: user.plan,
signupDate: user.createdAt,
},
});
}
}, { immediate: true });
</script>
<template>
<div>Welcome, {{ user?.firstName }}!</div>
</template>Set global properties
Properties set with setGlobalProperties are sent with every event. Use them for things like the app version or feature flags.
<script setup>
onMounted(() => {
window.pieowl('setGlobalProperties', {
app_version: '1.0.0',
environment: useRuntimeConfig().public.environment,
});
});
</script>Clear user data on logout
When a user logs out, clear the profile so new events are not linked to them.
<script setup>
function handleLogout() {
window.pieowl('clear');
navigateTo('/login');
}
</script>
<template>
<button @click="handleLogout">Logout</button>
</template>Set up server-side tracking
To track events in server routes, API endpoints or server middleware, use the @pieowl/sdk package. Server-side tracking needs a client secret.
Install the SDK
npm install @pieowl/sdkCreate a server instance
import { Pieowl } from '@pieowl/sdk';
export const pieowl = new Pieowl({
clientId: process.env.PIEOWL_CLIENT_ID!,
clientSecret: process.env.PIEOWL_CLIENT_SECRET!,
});Track events in server routes
Nuxt auto-imports what you export from server/utils, so pieowl is ready to use.
export default defineEventHandler(async (event) => {
const body = await readBody(event);
await pieowl.track('webhook_received', {
source: body.source,
event_type: body.type,
});
return { success: true };
});Never expose your client secret in the browser. Keep it in server-only code.
Awaiting in serverless environments
On a serverless platform like Vercel or Netlify, await the tracking call. That way it finishes before the function stops.
export default defineEventHandler(async (event) => {
// Always await in serverless environments
await pieowl.track('my_server_event', { foo: 'bar' });
return { message: 'Event logged!' };
});Track AI crawlers
AI crawlers and search bots don't run JavaScript, so the script never sees them. To count them, add @pieowl/bots as server middleware. It uses the same client secret.
npm install @pieowl/botsimport { trackBotRequest } from '@pieowl/bots';
export default defineEventHandler((event) => {
trackBotRequest({ url: getRequestURL(event).href, headers: getRequestHeaders(event) }, {
clientId: process.env.PIEOWL_CLIENT_ID!,
clientSecret: process.env.PIEOWL_CLIENT_SECRET!,
});
});Bypass ad blockers with proxy
Many ad blockers block requests to analytics domains. @pieowl/bots has a route handler that serves the script and sends events through your Nuxt server.
import { createRouteHandler } from '@pieowl/bots/route-handler';
export default fromWebHandler(createRouteHandler());Then point the script at that route in nuxt.config.ts, with the init form:
- Load the script from
/api/pieowl/pieowl.js, withoutdata-client-id - Set
apiUrl: '/api/pieowl'in theinitcall - All tracking requests now go through your Nuxt server
Browser extensions that block third-party analytics no longer see the requests.
Verify your setup
Open your Nuxt app and visit a few pages. Click the elements that send custom events. Then open the Pieowl dashboard and check the realtime view. Events should show up within seconds.
No events? Check the browser console for errors. The most common causes are:
- A wrong Client ID
- An ad blocker (add the proxy route)
The Network tab in your browser's developer tools shows whether requests are being sent.
Next steps
The script tag reference covers more features, such as profile counters and event filters. The Nuxt docs cover bot tracking and the proxy. To learn how Pieowl measures visits without cookies, read cookieless analytics.
Does Pieowl work with Nuxt 3 and Nuxt 4?
Yes. The script is added with app.head in nuxt.config.ts, which works the same in Nuxt 3 and Nuxt 4.
Do I need a Nuxt module?
No. Pieowl is one script tag in app.head. Call window.pieowl from any component in the browser.
Does Pieowl use cookies?
No. The tracker never sets a cookie and stores nothing on your visitors' devices. In many cases that means no consent banner for your analytics. See Do you need a cookie banner?.
How do I avoid ad blockers?
Add the proxy route from @pieowl/bots. All tracking requests then go through your Nuxt server at /api/pieowl/*, which ad blockers usually leave alone.
Does Pieowl help with GDPR?
Pieowl is built for GDPR: no cookies, no stored IPs. Your data is stored in the EU. Ask your legal advisor about your own setup.