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.