Skip to main content
5 min read

Add Zenovay Analytics to Astro

Zenovay Analytics gives Astro developers a lightweight, privacy-first way to understand how visitors interact with their sites. Whether you are building a static blog, a documentation site, or a content-driven marketing page with Astro, Zenovay drops in with a single script tag and starts collecting page views, referrers, device data, and geographic insights in real time. Unlike heavyweight analytics suites that slow down your Lighthouse score, the Zenovay tracker loads asynchronously in under 1 KB and never sets cookies by default, keeping your site fast and GDPR-friendly out of the box. This guide walks you through installation, custom event tracking, View Transitions support, and cookieless mode so you can go from zero to full analytics coverage in about two minutes.


Quick Setup (2 minutes)

Add the Zenovay tracking script to your Astro layout and you are done. No npm packages, no build plugins, no configuration files.

Step 1: Get Your Tracking Code

Sign in to your Zenovay dashboard and copy your tracking code from Settings → Tracking Code.

Step 2: Add to Layout

Open your main Astro layout file and add the script tag inside <head>:

src/layouts/Layout.astroASTRO
---
// src/layouts/Layout.astro
interface Props {
title: string;
}
const { title } = Astro.props;
---
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>{title}</title>
  <script
    defer
    data-tracking-code="YOUR_TRACKING_CODE"
    src="https://api.zenovay.com/z.js"
  ></script>
</head>
<body>
  <slot />
</body>
</html>

That's it! Zenovay will automatically track page views on every page that uses this layout.

Step 3: Verify Installation

Visit your site in a browser and open the Zenovay dashboard. You should see a real-time visitor appear within seconds.

Get your tracking code from the Zenovay Dashboard. Replace YOUR_TRACKING_CODE with your actual code.

Custom Events

Track button clicks, form submissions, and other interactions using the global zenovay function.

Inline Script in Astro Components

src/components/SignupButton.astroASTRO
---
// src/components/SignupButton.astro
interface Props {
plan: string;
}
const { plan } = Astro.props;
---
<button id="signup-btn" data-plan={plan}>
Sign Up for {plan}
</button>

<script>
const btn = document.getElementById('signup-btn');
btn?.addEventListener('click', () => {
  if (window.zenovay) {
    window.zenovay('track', 'signup_click', {
      plan: btn.dataset.plan,
    });
  }
});
</script>

Custom Events in Framework Components

If you use React, Vue, or Svelte islands inside Astro, call window.zenovay directly:

src/components/DownloadButton.tsx (React island)TSX
export default function DownloadButton({ file }: { file: string }) {
const handleClick = () => {
  if (window.zenovay) {
    window.zenovay('track', 'file_download', { file });
  }
};

return <button onClick={handleClick}>Download {file}</button>;
}

SPA Navigation with View Transitions

If you use Astro View Transitions, Zenovay automatically detects client-side route changes and records a new page view for each navigation. No extra configuration needed.

src/layouts/Layout.astro (with View Transitions)ASTRO
---
import { ViewTransitions } from 'astro:transitions';
---
<html lang="en">
<head>
  <ViewTransitions />
  <script
    defer
    data-tracking-code="YOUR_TRACKING_CODE"
    src="https://api.zenovay.com/z.js"
  ></script>
</head>
<body>
  <slot />
</body>
</html>

Zenovay listens for the browser History API (pushState / popstate) so it works with any client-side navigation method, including View Transitions.

Cookieless Mode

For privacy-friendly tracking without cookies or localStorage, add the data-cookieless attribute:

Cookieless trackingHTML
<script
defer
data-tracking-code="YOUR_TRACKING_CODE"
data-cookieless="true"
src="https://api.zenovay.com/z.js"
></script>

In cookieless mode, Zenovay uses a server-side hash of the visitor's IP subnet, user agent, and a daily-rotating salt to count unique visitors without storing anything on the client device.

Identify Users

If your Astro site has authenticated areas, identify logged-in users:

Identify a userJavaScript
// After login or on authenticated pages
if (window.zenovay) {
window.zenovay('identify', 'user_123', {
  email: '[email protected]',
  plan: 'pro',
});
}

Track Goals and Revenue

Goals and revenue trackingJavaScript
// Track a conversion goal
if (window.zenovay) {
window.zenovay('goal', 'newsletter_signup', { source: 'footer' });
}

// Track revenue
if (window.zenovay) {
window.zenovay('revenue', 49.99, 'USD');
}

TypeScript Support

Add type declarations so TypeScript recognizes window.zenovay:

src/env.d.tsTypeScript
/// <reference types="astro/client" />

declare global {
interface Window {
  zenovay?: (...args: any[]) => void;
}
}

Content Collections (Blog Analytics)

If you are using Astro Content Collections for a blog, every post automatically gets tracked as long as it renders through your layout. You can add post-specific metadata to events:

src/pages/blog/[...slug].astroASTRO
---
import { getCollection } from 'astro:content';
import Layout from '../../layouts/Layout.astro';

export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map((post) => ({
  params: { slug: post.slug },
  props: { post },
}));
}

const { post } = Astro.props;
const { Content } = await post.render();
---
<Layout title={post.data.title}>
<article>
  <h1>{post.data.title}</h1>
  <Content />
</article>
</Layout>

Zenovay captures the page URL and title automatically, so each blog post shows up as a separate page in your analytics dashboard.

Next Steps

Your Astro site is now tracking with Zenovay! View your analytics in the dashboard.

Continue learning:

Was this page helpful?