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.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.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:
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.
---
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:
<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:
// After login or on authenticated pages
if (window.zenovay) {
window.zenovay('identify', 'user_123', {
email: '[email protected]',
plan: 'pro',
});
}Track Goals and Revenue
// 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:
/// <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:
---
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:
- Custom Events - Advanced event tracking patterns
- Goals - Set up conversion goals
- Privacy Compliance - GDPR and CCPA configuration
- First-Party Tracking for Astro - Proxy the script through your own domain