Skip to content
Backpack
Esc
navigateopen⌘Jpreview
On this page

ADR 06: Self-hosted Umami for analytics

One analytics instance for the whole fleet.

Status: adopted (2026-07-15), standing workflow

Context

Every client site needs analytics without per-site SaaS fees or cookie banners.

Decision

Self-hosted Umami at analytics.backpackops.com. Every finished or ported site is registered there and carries the tracking script. This is a standing workflow: a site is not “done” until tracked. Credentials live in UMAMI_USERNAME and UMAMI_PASSWORD env vars only.

Mechanics

  • Registration is idempotent: check GET /api/websites?query=<domain> for an exact domain match before creating.
  • Static sites get the script injected into every page’s head (exports have no shared includes). porter/umami.py does this idempotently.
  • Next.js sites use an env-gated next/script with NEXT_PUBLIC_UMAMI_WEBSITE_ID and NEXT_PUBLIC_UMAMI_SRC.
  • The console resolves a site’s Umami entry by reading data-website-id off the live page, which stays correct before DNS cutovers when the registered domain (target apex) differs from the current Vercel alias.

Was this page helpful?