Umami Analytics Runbook
This runbook defines how IED uses Umami for the public web app and how to keep reporting clean.
Scope
- app:
apps/web - tracking provider: Umami script (
NEXT_PUBLIC_UMAMI_SCRIPT_URL) - website identifier:
NEXT_PUBLIC_UMAMI_WEBSITE_ID
Configuration
Required public env vars:
NEXT_PUBLIC_UMAMI_SCRIPT_URLNEXT_PUBLIC_UMAMI_WEBSITE_ID
Current implementation:
- Script is loaded in
apps/web/src/core/analytics/web-analytics-tracker.tsx - Pageviews are manually tracked on SPA route transitions
- First-load manual pageview is skipped to avoid duplicate initial hits
Event Taxonomy
Behavioral events (code)
assessment_start_viewassessment_postcode_unsupportedassessment_submittedcontact_page_viewcontact_submit_successcontact_submit_failedrecommendation_results_viewnext_step_viewnext_step_selected_pathfunnel_submission_successfunnel_submission_failed
CTA click events (data attributes)
All declarative CTA clicks use:
data-umami-event="cta_click"data-umami-event-id="..."data-umami-event-position="..."
This keeps click reporting simple while preserving action context.
Umami Dashboard Setup
Recommended funnels:
assessment_start_viewrecommendation_results_viewnext_step_selected_pathfunnel_submission_success
Recommended saved filters:
- by
selectedPath - by
batteryRecommendation - by
technicalReasonfor failure diagnostics
Data Quality Rules
- Keep event names stable (snake_case)
- Avoid renaming existing events without migration notes
- Keep metadata small and predictable
- Do not include raw personal data (email, full phone, full name) in event metadata
Verification Checklist
- Open home page and navigate to
/start,/results,/next-step,/confirmation - Submit contact form once (success path)
- Confirm pageviews appear in Umami realtime
- Confirm custom events appear with expected metadata
- Confirm
cta_clickevents includeidandpositiondimensions
Troubleshooting
No events appearing:
- verify
NEXT_PUBLIC_UMAMI_SCRIPT_URL - verify
NEXT_PUBLIC_UMAMI_WEBSITE_ID - inspect network requests to Umami host
- verify browser privacy/adblock rules are not blocking your self-hosted domain
Unexpected duplicate pageviews:
- verify first-load skip logic in tracker is present
- verify no duplicate script tags are rendered
Missing route transitions:
- verify
usePathname()updates and tracker component is mounted in root layout