Staats

Add analytics to Astro

A cookieless tracker for Astro, with the one directive that stops it being stripped from your build.

The install

Put the snippet in the <head> of your base layout, usually src/layouts/Layout.astro, so every page that uses the layout is covered:

---
// src/layouts/Layout.astro
---
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <script is:inline defer data-site="YOUR_SITE_CODE" src="https://www.staats.ai/s.js"></script>
  </head>
  <body>
    <slot />
  </body>
</html>

Why is:inline matters here

This is the part that catches people. Astro processes and bundles <script> tags it finds in components by default. That is usually what you want for your own code, and exactly what you do not want for a third-party tag: the script gets pulled into Astro's build pipeline instead of being emitted as a plain tag pointing at our CDN.

The is:inline directive tells Astro to leave the tag alone and output it verbatim. Without it, the symptom is quiet: your build succeeds, the page loads, and no events arrive. If you have installed a tracker in Astro before and found it silently doing nothing, this was almost certainly why.

View transitions and client routing

If you use <ClientRouter /> for view transitions, you do not need to do anything else. The tracker hooks pushState, replaceState and popstate, so navigations that never trigger a full page load are still recorded as pageviews. There is no route-change listener to wire up and no astro:page-load handler to write.

Tracking a click

Add a data-track attribute to any clickable element in an .astro file. No client-side JavaScript, and no client:load directive, because the tracker uses a single delegated listener:

<a href="/signup" data-track="signup_click">Get started</a>

For anything that is not a click, such as a form submission handler, call window.track directly:

window.track('newsletter_signup')

No cookie banner

The script is around 1.5KB, sets no cookies, and stores nothing on the visitor's device. Visitors are counted with a pseudonymous hash that rotates daily, and country comes from the browser timezone rather than an IP lookup. There is nothing to ask consent for, so a static Astro site stays static and fast, with no consent dialog in front of your content.

Local development

You can leave the snippet in place while you work. Anything served from localhost or opened over file:// is never recorded, so astro dev will not pollute your production numbers. One thing to watch: if you have a custom src/pages/404.astro that uses the same layout, every mistyped URL and crawler probe lands in your stats as a real page. Give your 404 its own layout without the snippet.

Reading the data

Staats has no dashboard. You connect it to your coding agent once, and then you ask. Because the connection is a Model Context Protocol server, the agent can pull traffic, referrers, and funnels into the conversation you are already having about the code.

> did the new pricing page help?

The agent also stores what the site is for and what each event means, so a question three weeks later does not start from nothing. See MCP Server and Agent Workflows.

Get a site code

Create a free account, add your site, and paste the snippet above. The free plan covers side projects, and there is no card required.