Help Center / Troubleshooting and updates
07 · Troubleshooting & updates
A short verification routine, the fixes for the problems that actually happen, and the update paths that keep your install in sync with the repo.
On your tracked site, open DevTools → Console and run:
Measr.enableDebug();
Reload. Every event now prints a collapsible console group like [Measr] page_view — expand it to see the page, the site, and the event's data fields as the SDK detected them (identifiers are resolved server-side and never exist in the browser). Alternatives: append ?debug=analytics to any URL — note it sets the same persistent toggle, so it stays on until you run Measr.disableDebug(). The toggle lives under the localStorage key measr_analytics_debug — the only localStorage key Measr ever touches; the SDK reads it on load so your choice survives reloads, only you ever write it (never for a visitor), and turning debug off removes it. For the complete outgoing payload, use the Network tab in the next step.
The console line prints before the HTTP request, so a log alone proves nothing. Open the Network tab and look for POST requests to /functions/v1/measr-ingest on your Supabase URL — click one and inspect the payload to see precisely which fields leave the browser (as of v1.3.0 every event travels through this one endpoint; there are no direct table writes). If a request failed, run Measr.getLastErrors() in the console for the 20 most recent failures with status and message. Then open Table Editor → analytics_events in Supabase: rows with your siteId are the ground truth.
Sign in, set the range to Last 7 days, and confirm the Sessions KPI is at least 1. For a per-event-type walkthrough (scroll, forms, downloads, errors, and the rest), run the full script in docs/QA.md.
| Symptom | Cause and fix |
|---|---|
| Dashboard shows 0 for everything | Check three things in order. First: the siteId in Measr.init() must match VITE_DEFAULT_SITE in the dashboard env file. Second: rows must exist in Table Editor → analytics_events; if not, the SDK config has a typo. Third: the site picker in the dashboard header must show your site. |
| Signed in, but every panel is empty | The auth user has no data-access claim. Tenant isolation is fail-closed. Open Authentication → Users → your user → App Metadata and set {"is_admin": true} or {"allowed_sites": ["your-site-id"]}, then sign out and back in so the token refreshes. |
[Measr] logs appear, no rows in Supabase |
Console logs fire before the request. Check the Network tab for failed POSTs to /functions/v1/measr-ingest, and run Measr.getLastErrors() for the status and message of recent failures. Usual causes: the edge function is not deployed, or a typo in the Supabase URL. Changing siteId needs no cache clearing: sessions are resolved server-side per visitor and site, so a new siteId simply opens its own session. |
Missing VITE_SUPABASE_URL at build time |
The env file is in the wrong place. It must be inside dashboard/, not the repo root. Vite reads .env.production for builds and .env.development for npm run dev. |
Invalid login credentials |
The user must exist in Authentication → Users, created through the Supabase UI. Users inserted via SQL have no usable password hash. |
| Password reset email missing or link rejected | Under Authentication → URL Configuration, confirm the dashboard URL is on the redirect allow list. For production, verify custom SMTP and its delivery logs. Expired links are rejected by design; return to sign in and request a fresh one. |
new row violates row-level security policy |
The migrations didn't run completely, or 005_rls_policies.sql was skipped. Re-run it; it is safe to apply again. |
| "Chunks larger than 500 kB" build warning | Cosmetic. The dashboard ships as a single bundle by design. Ignore it. |
When a new version ships, the update email lists exactly which files changed and which migrations are new.
Open the Measr folder and say:
update Measr
The built-in update skill pulls the latest code, identifies what changed (SDK files, migrations, dashboard), and walks you through applying each piece.
git pull origin main in your Measr folder.sdk/measr.js into your website project, replacing the old file. Clear the browser cache afterwards..sql files numbered higher than the last one you ran, in order, via the SQL Editor or supabase db push. Skip the ones flagged Measr-internal in SETUP.md.npm ci && npm run build in dashboard/, then redeploy dist/.New pages, renamed CTAs, or a redesigned nav can leave your tracking out of date. With Claude Code, open the Measr folder and say:
my site changed
The maintain skill re-scans your site, diffs against the last known event map, shows you what's new, removed, or renamed, and implements only what you approve.
The rate-limit tables accumulate one row per bucket per window (day-scoped hashed buckets on the current ingestion path; raw-IP keys on the legacy direct-insert path and the newsletter endpoint). On hosted Supabase, a scheduled job (migration 045) cleans them daily at 03:00 UTC; verify it with:
SELECT jobname, schedule, active FROM cron.job WHERE jobname = 'cleanup-rate-limits';
On self-hosted Postgres without pg_cron, run the two DELETE statements from docs/MAINTENANCE.md on a daily schedule of your choice.
Your database, your rules. Authenticated users with the right claim can delete by session, by date range, or in bulk via SQL directly in Supabase. Nothing is retained anywhere else.
Open an issue on the repository or email support@measr.app. Include the browser console output and, if the problem is on the ingest side, a screenshot of the Network tab.
siteId and VITE_DEFAULT_SITE don't match, the auth user has no data-access claim, or events never reached Supabase. The table above walks through each.