All integration guides

Integration guide

Analytics in Astro

A <script> in your layout loads the SDK on every page. Static sites need nothing else; with view transitions, an Astro event counts each navigation.

Before you start

  • Astro 3 or newer.
  • Your site_key, and your domain under Allowed origins.

Installation

  1. 1Install the SDK

    In Astro, variables available in the browser start with PUBLIC_.

    npm install @racoelho/analytics
    .env
    PUBLIC_ANALISA_SITE_KEY=YOUR_SITE_KEY
  2. 2Create the instance in a module

    Astro scripts are bundled and run once per page load, even when the module is imported by several components.

    src/lib/analytics.ts
    import { Analytics } from '@racoelho/analytics'
    
    // imported by several scripts: Astro bundles it once, so there is one instance
    export const analytics = new Analytics({
      siteKey: import.meta.env.PUBLIC_ANALISA_SITE_KEY,
    })
  3. 3Import it in the layout

    Use the same layout on every page. The first pageview goes out when the module loads.

    src/layouts/Layout.astro
    ---
    const { title } = Astro.props
    ---
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>{title}</title>
      </head>
      <body>
        <slot />
        <script>
          import { analytics } from '../lib/analytics'
    
          // with <ClientRouter /> (view transitions): count each navigation
          document.addEventListener('astro:page-load', () => analytics.pageview())
        </script>
      </body>
    </html>

Events and goals

In any .astro component, a <script> imports the same instance and calls track(name, properties).

src/components/Hero.astro
<button id="signup">Sign up</button>

<script>
  import { analytics } from '../lib/analytics'

  // delegated on document: keeps working after view transitions
  document.addEventListener('click', (event) => {
    if (event.target instanceof Element && event.target.closest('#signup')) {
      analytics.track('signup_click', { place: 'hero' })
    }
  })
</script>

Create an event goal named signup_click in the dashboard. For thank-you pages, a path goal is enough.

Page navigation

Without view transitions, each page is a full load and counts itself. With <ClientRouter />, Astro swaps pages without reloading and the SDK does not notice — the astro:page-load listener in the layout covers it (on first load it repeats the pageview, and the SDK drops the duplicate).

Check that it works

  1. Open the published site in a normal window, with no ad blocker.
  2. In your browser devtools, Network tab, filter by v1/i: you should see a POST with status 200 within 3 seconds (or when you leave the page).
  3. In the dashboard, events show up in about 30 seconds.
  4. If you use view transitions, navigate between two pages and look for a new page_view.

Troubleshooting

With view transitions, clicks stop counting after a navigation
Bundled scripts run only once; a listener attached to a button is lost when Astro swaps the page content. Listen on document and filter by target, as in the example.
The request returns 403 (origin_not_allowed)
Your domain isn’t in Allowed origins in the site settings. Add the exact origin — with https://, with and without www, plus test addresses like http://localhost:3000 if you want to measure in development.
No request shows up in the Network tab
The SDK honors Do Not Track by default: if your browser sends DNT, nothing is sent. Test in another browser or profile. Ad blockers can also block the script.
Pageviews show up twice
The SDK was initialized twice (for example, pasted in the theme and also added by a plugin). Keep a single instance per page.

Create your account and grab the site_key

Free up to 10K events a month, no credit card.

Create a free account
Astro analytics: layout and view transitions · Analisa