Skip to content
A Astro Rocket

Umami Analytics: Cookieless, Built In

Umami works out of the box: private, cookieless web analytics. Set one environment variable and you get visitor numbers with no cookie banner.

H

Hans Martens

8 min read
Table of contents Show Hide

Astro Rocket has always shipped with built-in support for Google Analytics 4 and Google Tag Manager — set an environment variable and the tracking script loads itself. Now there’s a third option that a lot of people have been asking for: Umami. It works exactly the same way — one environment variable and you’re done — but it’s privacy-friendly and cookieless by design.

This post covers what Umami is, how the theme wires it up for you, and how to turn it on for your own site.

What Umami is

Umami is an open-source, privacy-focused web analytics tool — a lightweight alternative to Google Analytics. It gives you the numbers you actually care about (page views, visitors, referrers, top pages, countries, devices) in a clean dashboard, without the weight and complexity of a full marketing-analytics stack.

The important part is how it collects those numbers:

  • No cookies. Umami doesn’t set any cookies and doesn’t track people across sites.
  • No personal data. It stores no personally identifiable information, so under the GDPR and similar laws you generally don’t need a cookie-consent banner for it.
  • Tiny. The tracking script is only a couple of kilobytes, so it barely touches your page-load performance.
  • Yours. It’s open source (MIT). You can use the hosted Umami Cloud service, or run Umami on your own server and keep every byte of your data in-house.

In short: real analytics, without the privacy trade-offs — a good fit for the kind of fast, respectful sites Astro Rocket is built for.

How it works in Astro Rocket

Umami lives in the same place as the other analytics providers — the theme’s Analytics component (src/components/layout/Analytics.astro), which is already included in the base layout on every page. You don’t edit any component code. The whole feature is driven by two environment variables:

Variable Required? What it does
PUBLIC_UMAMI_WEBSITE_ID Yes (to enable) The website ID (a UUID) from your Umami dashboard. Setting it switches Umami on.
PUBLIC_UMAMI_SRC No The tracking-script URL. Defaults to https://cloud.umami.is/script.js. Set it when your snippet’s src differs — because you self-host, or because your account is on another Umami Cloud instance.

When PUBLIC_UMAMI_WEBSITE_ID is set, the theme adds this to your pages automatically:

<script async src="https://cloud.umami.is/script.js" data-website-id="your-website-id"></script>

When it’s not set, nothing is added — no script, no requests. And because Umami is cookieless, the script loads directly and is not tied to the cookie-consent flow: there are no cookies to ask permission for.

You can run more than one. Umami is independent of Google Analytics and Google Tag Manager. Set PUBLIC_UMAMI_WEBSITE_ID on its own for a Google-free setup, or run it alongside GA4 if you want both. They don’t interfere with each other.

How to use it yourself

Step 1 — Get a Umami website ID

You have two ways to get Umami running:

  • Umami Cloud (easiest): sign up at cloud.umami.is, which has a free tier that’s plenty for a personal site. Add your website, and Umami gives you a Website ID (a UUID that looks like xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx). Copy it.
  • Self-hosted: follow the Umami install guide to run it on your own server (Docker, a VPS, wherever you like). Add your website in your own dashboard and copy its Website ID from there.

When you add the website, Umami asks for a Domain. Enter your bare hostname — yoursite.com, with no https://, no www. unless you really serve the site from there, and no trailing slash. Umami checks incoming events against this field and rejects the ones that do not match, so a small mistake here means the script loads, the page looks fine, and nothing is ever recorded.

Umami then shows you a tracking snippet for that website:

<script defer src="https://cloud.umami.is/script.js" data-website-id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"></script>

Copy both values out of it — the data-website-id and the src. Take them from your own dashboard rather than from this page: Umami Cloud runs more than one instance, including a European one, and a website created on one does not exist on the other. If your src is not https://cloud.umami.is/script.js, you will need PUBLIC_UMAMI_SRC in step 3 even though you are not self-hosting.

Step 2 — Set the environment variable

For local development, add it to the .env file at your project root:

PUBLIC_UMAMI_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

For production on Vercel, open your project and go to Settings → Environment Variables, then add:

  • Name: PUBLIC_UMAMI_WEBSITE_ID
  • Value: your Website ID
  • Environment: Production (and Preview too, if you want stats on preview deployments)

That’s the only variable you need for Umami Cloud. The script URL defaults to Cloud, so you can leave PUBLIC_UMAMI_SRC unset.

Step 3 — Point the script at the right instance

Set PUBLIC_UMAMI_SRC when the src you copied in step 1 is anything other than https://cloud.umami.is/script.js — either because you self-host, or because your account is on a different Umami Cloud instance:

PUBLIC_UMAMI_SRC=https://analytics.yourdomain.com/script.js

Leave it out when your snippet’s src already matches the default.

Step 4 — Redeploy

Environment-variable changes don’t apply to a deployment that’s already running. Trigger a new deploy so the variable is picked up:

  1. In Vercel, go to Deployments
  2. Open the three-dot menu on your latest deployment and choose Redeploy

Or just push any small change to your main branch — Vercel builds and deploys automatically.

Step 5 — Check it’s working

Open your live site in a normal window — ad blockers stop Umami, so an incognito window with one running will show you nothing.

Then open your browser’s developer tools, go to the Network tab, type send in the filter box, and reload. You are looking for a POST to /api/send coming back 200 or 204.

Check that request, not just the script.js one. The script loads successfully even when every event it sends is being rejected, so a page that looks fine and a dashboard that stays empty is the normal shape of this going wrong. A 400 here means the events are reaching Umami and being refused — see the troubleshooting table below.

With a 200, open the Realtime view in Umami and you should see yourself within a few seconds.

Step 6 — Stop counting yourself

On a site with modest traffic your own visits will outnumber everyone else’s, and the numbers stop meaning anything. Umami’s tracker checks localStorage for a flag and skips sending when it finds one. On your live site, open the developer tools Console and run:

localStorage.setItem('umami.disabled', 1)

Reload and check the Network tab again: there should now be no request to /api/send at all. To start counting yourself again:

localStorage.removeItem('umami.disabled')

This is stored per browser profile, per device and per site, so repeat it on your phone and in any other browser you use, and expect to redo it if you clear the site’s data. It also means the flag you set on one of your sites does nothing on another.

Blocking the script host in an ad blocker works too and follows you between profiles — but then you can never check that tracking still works, which is how a broken setup goes unnoticed for months.

Troubleshooting

Problem Likely cause
No data in the dashboard The env variable wasn’t set, or the site wasn’t redeployed after adding it. Re-run the deployment.
/api/send returns 400 Umami received the events and refused them. Either the Domain on the website record does not match the site sending them, or the Website ID belongs to a different Umami instance than the script URL. Check the Domain field first.
Script loads, dashboard stays empty Same cause as the row above. A loaded script.js only proves the file was fetched, not that anything was accepted. Check /api/send in the Network tab.
Still nothing after a redeploy Double-check the Website ID is exactly the UUID from your dashboard, with no extra spaces.
Works locally but not in production The variable was added to .env but not to Vercel’s environment variables (or only to Preview, not Production).
Self-hosted instance shows no hits PUBLIC_UMAMI_SRC is missing or points at the wrong URL — it must be your instance’s script.js.
Your own visits inflate the numbers Expected on a new site, and worth switching off — see below.

That’s the whole setup

One environment variable for Umami Cloud, two if you self-host — no component edits, no cookie banner, no performance hit worth mentioning. It sits quietly alongside the Google Analytics and Google Tag Manager support that was already there, so you can pick the analytics that fit how you want to treat your visitors.

If you’d like to see the rest of what the theme includes, browse the other feature posts or grab the theme on GitHub.

Share:

Related Posts

Five Footer Layouts, and the One That Ships

Simple, minimal, stacked, centered and columns. The default builds its own columns from your nav, your tags and your projects, and shrinks back to a single row when a site has nothing to put in them.

H Hans Martens
5 min read
#astro-rocket #features #footer #navigation #customization

Newsletter Signup: Collect Subscribers

A signup that posts to a Resend audience, in the footer of every page. On by default, and it tells you when its keys are missing instead of waiting for a visitor to find out.

H Hans Martens
7 min read
#astro-rocket #features #newsletter #resend #forms

The Click-to-Play YouTube Embed

Embed a YouTube video with one component. The page ships only a thumbnail; the player loads from youtube-nocookie.com on play, so Lighthouse stays at 100.

H Hans Martens
3 min read
#astro-rocket #features #components #performance

Ready to build?

Clone Astro Rocket, pick a theme, and launch your next project in minutes.