/ astro-integrations / How to Integrate Pirsch with Astro: Complete Guide
astro-integrations 5 min read

How to Integrate Pirsch with Astro: Complete Guide

Step-by-step guide to integrating Pirsch with your Astro website. Setup, configuration, and best practices.

How to Integrate Pirsch with Astro: Complete Guide

Pirsch is a privacy-friendly, cookie-free web analytics platform made in Germany. It tracks page views, referrers, devices, and other visitor metrics without using cookies or collecting personal data, making it GDPR compliant by default. Since Pirsch does not require cookie consent banners, it is a clean choice for Astro sites where you want analytics without the overhead of managing user consent flows.

This guide covers adding Pirsch to an Astro project using both the client-side script approach and the server-side API for more advanced tracking scenarios.

Prerequisites

Before starting, you will need:

  • Node.js 18+ installed
  • An existing Astro project (any version)
  • A Pirsch account (free tier available at pirsch.io)
  • A website added to your Pirsch dashboard with an identification code or access key

Pirsch works with static Astro sites. No SSR adapter is required for the basic script integration.

Installation

Pirsch does not require any npm packages for the basic script-based setup. You embed a lightweight tracking script directly in your HTML.

For server-side tracking, install the official SDK:

npm install pirsch-sdk

Configuration

The simplest integration method is adding the Pirsch tracking script to your base layout. Get your identification code from Pirsch Dashboard > Settings > Integration.

---
// src/layouts/BaseLayout.astro
---

<html>
  <head>
    <meta charset="utf-8" />
    <title>My Astro Site</title>
    <script
      defer
      type="text/javascript"
      src="https://api.pirsch.io/pa.js"
      id="pianjs"
      data-code="YOUR_IDENTIFICATION_CODE"
    ></script>
  </head>
  <body>
    <slot />
  </body>
</html>

Replace YOUR_IDENTIFICATION_CODE with the code from your Pirsch dashboard. The script is about 1KB, loads asynchronously with defer, and does not block page rendering.

Using an Environment Variable

Store the identification code in .env:

PUBLIC_PIRSCH_CODE=YOUR_IDENTIFICATION_CODE

Then reference it in your layout:

---
const pirschCode = import.meta.env.PUBLIC_PIRSCH_CODE;
---

<html>
  <head>
    <script
      defer
      type="text/javascript"
      src="https://api.pirsch.io/pa.js"
      id="pianjs"
      data-code={pirschCode}
    ></script>
  </head>
  <body>
    <slot />
  </body>
</html>

Method 2: Server-Side Tracking

For SSR Astro sites, you can track page views server-side instead of using a client script. This approach is invisible to ad blockers and gives you more control over what gets tracked.

First, add your Pirsch credentials to .env:

PIRSCH_CLIENT_ID=your_client_id
PIRSCH_CLIENT_SECRET=your_client_secret
PIRSCH_HOSTNAME=yourdomain.com

Create a Pirsch client utility:

// src/lib/pirsch.ts
import { Pirsch } from 'pirsch-sdk';

let client: Pirsch | null = null;

export function getPirschClient() {
  if (client) return client;

  client = new Pirsch({
    clientId: import.meta.env.PIRSCH_CLIENT_ID,
    clientSecret: import.meta.env.PIRSCH_CLIENT_SECRET,
    hostname: import.meta.env.PIRSCH_HOSTNAME,
  });

  return client;
}

Server-Side Middleware

Track every page view through Astro middleware:

// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getPirschClient } from './lib/pirsch';

export const onRequest = defineMiddleware(async ({ request }, next) => {
  const response = await next();

  // Only track HTML page views, not assets
  const contentType = response.headers.get('content-type') || '';
  if (contentType.includes('text/html')) {
    const pirsch = getPirschClient();
    const url = new URL(request.url);

    try {
      await pirsch.hit({
        url: url.pathname,
        ip: request.headers.get('x-forwarded-for') || request.headers.get('cf-connecting-ip') || '',
        user_agent: request.headers.get('user-agent') || '',
        accept_language: request.headers.get('accept-language') || '',
        referrer: request.headers.get('referer') || '',
      });
    } catch (error) {
      // Silently fail - analytics should never break the page
      console.error('Pirsch tracking error:', error);
    }
  }

  return response;
});

Common Patterns

Tracking Custom Events

Pirsch supports custom events for tracking specific user interactions. With the client-side script:

<button id="download-btn">Download Guide</button>

<script>
  document.getElementById('download-btn')?.addEventListener('click', () => {
    if (typeof pirsch === 'function') {
      pirsch('Download Guide', { duration: 0, meta: { type: 'pdf' } });
    }
  });
</script>

Handling Astro View Transitions

Pirsch's script automatically detects page changes for standard navigation. For Astro View Transitions, the script handles SPA-style navigations correctly since it watches for URL changes. If you notice missed page views, add a manual trigger:

<script>
  document.addEventListener('astro:page-load', () => {
    if (typeof pirsch === 'function') {
      pirsch('pageview');
    }
  });
</script>

Excluding Routes from Tracking

If certain pages should not be tracked (admin pages, preview routes), filter them in your middleware:

const excludedPaths = ['/admin', '/preview', '/api'];
const shouldTrack = !excludedPaths.some(path => url.pathname.startsWith(path));

if (shouldTrack) {
  await pirsch.hit({ /* ... */ });
}

Dashboard Filtering

Pirsch provides filtering in its dashboard for UTM parameters, referrers, countries, and custom events. Set up UTM tracking in your marketing links (e.g., ?utm_source=twitter&utm_campaign=launch) and Pirsch automatically parses and displays them.

Troubleshooting

No data in dashboard after setup: Pirsch filters out localhost traffic by default. To test locally, temporarily add localhost as an allowed domain in your Pirsch dashboard settings, or test with your production deployment.

Script blocked by ad blockers: Some ad blockers may block api.pirsch.io. If this is a concern, use the server-side tracking approach which is completely invisible to browser extensions. Pirsch also offers a custom domain proxy feature for their script.

Page views counted twice: If you are using both the client-side script and server-side middleware, you will get duplicate hits. Choose one approach per project. The client-side script is simpler. Server-side tracking is more accurate but requires SSR.

Server-side IP address wrong: Behind reverse proxies, the IP address comes from headers like x-forwarded-for or cf-connecting-ip (Cloudflare). Make sure your middleware reads the correct header for your hosting setup. Pirsch needs the real visitor IP for geo-location and unique visitor counting.

Events not appearing: Custom events may take a few minutes to appear in the Pirsch dashboard. Also verify that the global pirsch function is available by checking that the script loaded successfully in your browser's network tab.

Conclusion

Pirsch offers a straightforward analytics solution for Astro sites that values simplicity and privacy. The client-side script requires zero configuration beyond pasting a code snippet, while server-side tracking gives you ad-blocker-proof accuracy for SSR projects. Since Pirsch does not use cookies, you can skip the consent banner entirely and focus on building your site. The dashboard provides the metrics that matter, such as page views, referrers, devices, and geographic data, without the complexity of Google Analytics.