add-umami-analytics
Skill1 starsChanged 4 months agoMITView on GitHub
Add umami analytics plus automatic click/event tracking (every link and button) to any website. Creates a umami website project, injects the tracking script, and wires detailed event tracking that logs who clicks what. Defaults to Umami Cloud; targets a self-hosted instance via environment variables. Use when the user wants to add analytics, tracking, page-view stats, or per-element click/event logging to a site.
- Reads credentials
- Sends data out
In this repository9 other files it gives its agents.
- amazon-writingSkill
- brand-namingSkill
- creativity-rejectionismSkill
- explain-diff-notionSkill
- explain-diffSkill
- explain-notionSkill
- explainSkill
- fetch-paperSkill
- ml-paper-writingSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 27
Instead, the website id comes from the environment, so a fork that lacks it collects nothing:
- Very specific: line 30
Pure static sites (GitHub Pages, no build): commit only placeholders (__UMAMI_WEBSITE_ID__, __UMAMI_SCRIPT_URL__) and inject them at deploy …
- Very specific: line 57
Add the umami script to the root layout <head> (Next.js: next/script, strategy="afterInteractive"), reading the ID from env and guarding by …
- Very specific: line 68
Import and mount <UmamiEvents /> once in the layout body.
- Distinctive: line 91
Follow the user's git workflow.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Add Umami Analytics + Event Tracking
Adds privacy-focused umami analytics to any website and layers on automatic event tracking for every <a>, <button>, role="button", and submit/button input — no manual tagging. Event name is the element's readable label (e.g. link: Resume, button: Contact); href, id, text, and page path are stored as event properties.
Configuration (environment)
The skill targets Umami Cloud by default. Point it at a self-hosted instance purely through environment variables — no specific server or website ID is baked into these files.
UMAMI_SCRIPT_URL— the tracking script URL injected into pages. Defaults tohttps://cloud.umami.is/script.js. Set to your own instance's/script.jsto self-host.UMAMI_REPO— (self-hosted website creation) path to a umami repo linked to its host (e.g. Vercel). When set,create-website.shcreates the website directly via the instance's Postgres DB.UMAMI_API_KEY/UMAMI_API_URL— (cloud website creation) Umami Cloud API key;UMAMI_API_URLdefaults tohttps://api.umami.is/v1.
Resolve the script URL in shell as:
SCRIPT_URL="${UMAMI_SCRIPT_URL:-https://cloud.umami.is/script.js}"Fork protection (important)
Tie tracking to the project's deployment environment, never to a domain. Do NOT gate on hostname (e.g. umami's data-domains): the owner may serve the site from many domains and add more over time, so domain gating silently drops real traffic. umami already records hostname on every event, so you can always filter by domain after the fact — just never gate on it.
Instead, the website id comes from the environment, so a fork that lacks it collects nothing:
- Projects with a build/env (Next.js, Vite, Astro…): read the id from a public env var —
NEXT_PUBLIC_UMAMI_WEBSITE_ID,VITE_UMAMI_WEBSITE_ID, etc. Set it in the host's project settings (Vercel/Netlify) + local.env. A fork without it renders no script. - Pure static sites (GitHub Pages, no build): commit only placeholders (
__UMAMI_WEBSITE_ID__,__UMAMI_SCRIPT_URL__) and inject them at deploy from per-repo GitHub Actions variables usingassets/pages-inject.yml. A fork without theUMAMI_WEBSITE_IDrepo variable deploys an empty id → tracks nothing. See step 3B.
Procedure
1. Get a website ID
- If the site already has a umami snippet (grep for
data-website-id), reuse that ID to preserve historical continuity — only change thesrcto$SCRIPT_URL. - Otherwise create a website and capture the printed UUID:
The script auto-selects a mode from the environment: self-hosted DB insert (bash scripts/create-website.sh "<name>" "<domain>"UMAMI_REPOset), Umami Cloud API (UMAMI_API_KEYset), or — if neither — it prints instructions to create the website in the dashboard and copy its ID.
Store the ID in the project's env (see Fork protection), not inline, wherever the framework supports it.
2. Detect the project type
- Next.js App Router —
src/app/layout.tsx(orapp/layout.tsx) - Next.js Pages Router —
pages/_app.tsx/pages/_document.tsx - Vite / CRA / plain SPA — root
index.html(+ env viaimport.meta.env) - Static site / GitHub Pages — each
index.html(and other*.html) - Astro / SvelteKit / Nuxt — the framework's root layout template
3. Inject tracking
A. React / Next.js (one listener survives SPA navigation):
- Copy
assets/umami-events.tsxinto the components dir (match the import alias). - Add the umami script to the root layout
<head>(Next.js:next/script,strategy="afterInteractive"), reading the ID from env and guarding by domain:
Set{process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID && ( <Script src={process.env.NEXT_PUBLIC_UMAMI_SCRIPT_URL ?? "https://cloud.umami.is/script.js"} data-website-id={process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID} strategy="afterInteractive" /> )}NEXT_PUBLIC_UMAMI_WEBSITE_ID(and optionallyNEXT_PUBLIC_UMAMI_SCRIPT_URL) in the host's env + local.env. Nodata-domains— do not gate on domain. - Import and mount
<UmamiEvents />once in the layout body.
B. Static HTML / non-React — inject the block from assets/umami-tracker.html before </head> in every HTML entry file, keeping the __UMAMI_SCRIPT_URL__ / __UMAMI_WEBSITE_ID__ placeholders (do not inline real values). Then wire deploy-time injection:
- Copy
assets/pages-inject.ymlto.github/workflows/pages.yml. It substitutes the placeholders from repo variables and deploys to Pages. - Set the repo variables:
gh variable set UMAMI_WEBSITE_ID --repo <owner/repo> --body "<id>"(andUMAMI_SCRIPT_URLif self-hosting). - Switch Pages source to Actions:
gh api --method PUT repos/<owner/repo>/pages -f build_type=workflow.
A fork lacking the UMAMI_WEBSITE_ID variable deploys an empty id → tracks nothing. No data-domains.
For Astro/Svelte/Nuxt, adapt the same two pieces (script tag + inline IIFE listener) into the layout template, reading the ID from the framework's public env.
4. Verify (optional)
Send a synthetic event to the instance's /api/send (base = $SCRIPT_URL's origin) and check for 200:
BASE="$(dirname "${UMAMI_SCRIPT_URL:-https://cloud.umami.is/script.js}")"
curl -s -X POST "$BASE/api/send" -H 'Content-Type: application/json' -H 'User-Agent: Mozilla/5.0' \
-d '{"type":"event","payload":{"website":"WEBSITE_ID","hostname":"DOMAIN","url":"/","title":"test","name":"button: verify","data":{"type":"button"}}}'(Test rows — delete afterward if verifying against a real site.)
5. Commit
Follow the user's git workflow. Commit the injected files. Only push if the user asked you to — confirm push scope per repo.
Notes
- Event names are truncated to 50 chars (umami's
event_namelimit); full text/href live in properties. - The listener uses capture phase so clicks that call
stopPropagationare still recorded. - One umami "website" can span multiple hostnames; every event records its
hostname, so filter by domain in the dashboard rather than gating on it. - View data by logging into your umami instance → the website → Events tab.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

