Help Center / Manual setup
03 · Manual setup
The hands-on path. It assumes you have never used Supabase and takes about 30 minutes. If you would rather have an assistant drive, use the guided setup instead.
git clone https://github.com/Batu75/measr.git
cd measr
Everything is in here: the SDK (sdk/), the migrations (database/migrations/), the dashboard (dashboard/), and the docs (docs/).
Go to supabase.com, create a free account, and click New Project. Name it anything, set a database password (save it, Supabase will not show it again), pick a region close to your users, and wait about two minutes for it to spin up.
Then collect your two credentials from Settings → API:
https://xxxxx.supabase.coeyJhbGci...The anon key is safe to ship in client-side code. The current SDK sends every event through the measr-ingest edge function, and the key itself retains only the legacy write-only grants — it can never read, change, or delete analytics.
The migrations create the three analytics tables, the server-side functions the dashboard calls, and the row-level security policies.
Option A, SQL Editor (no CLI needed): in the Supabase dashboard, open SQL Editor → New query. Open database/migrations/001_extensions.sql from the repo, paste it, click Run. Repeat for each file in numeric order. Each should return "Success. No rows returned". If you see a red error banner, stop and fix that migration before continuing.
Option B, Supabase CLI:
supabase link --project-ref <your-project-ref>
supabase db push
Your project ref is under Settings → General → Reference ID.
Skip the internal-only migrations. A few files are flagged in docs/SETUP.md as Measr-internal (for example 024, the newsletter table; a few older numbers such as 010, 018, and 020 are superseded safe no-ops). The notes next to each file in SETUP.md say which ones to skip on a customer install.
Afterwards you should see three tables in the Table Editor: analytics_events, analytics_sessions, analytics_video_events.
Then deploy the ingestion edge function — the v1.3.0 SDK sends every event through it, so without this step no data arrives:
supabase functions deploy measr-ingest --project-ref <your-project-ref> --no-verify-jwt
(--no-verify-jwt makes the endpoint publicly callable — tracking runs before any login; the function itself validates and rate-limits every request. No secrets to configure.)
Copy the sdk/ folder into your web project so it sits next to your HTML files, then add this near the top of your page with your real values:
<script type="module">
import Measr from './sdk/measr.js';
Measr.init({
supabaseUrl: 'https://xxxxx.supabase.co',
supabaseKey: 'eyJhbGci...',
siteId: 'my-site', // any short label; pick one and stick with it
debug: true, // temporary, for the quick check below
});
</script>
That's it for most tracking. The SDK auto-detects page views, interactions, navigation, exit links, scroll depth, downloads, and errors. Only video and forms need manual wiring, covered in tracking modules.
Quick check: reload your page and watch the browser console for [Measr] groups — these print before the request, so also confirm a successful POST to /functions/v1/measr-ingest in the Network tab. Then open Table Editor → analytics_events in Supabase. If rows with your siteId appear, run Measr.disableDebug() in the console and continue. If not, check that the edge function from step 3 is deployed and run Measr.getLastErrors() for details.
The dashboard requires a login. In Supabase, open Authentication → Users → Add user → Create new user. Enter an email and password and leave Auto Confirm User checked.
Then grant data access. Tenant isolation is fail-closed: a user without an access claim signs in and sees empty panels. On the user's row, open App Metadata and set one of:
{"is_admin": true} for a single-site install or your own admin account (sees every site){"allowed_sites": ["my-site"]} to scope the account to specific site IDsEnable password recovery. Under Authentication → URL Configuration, set the Site URL to your deployed dashboard and add every dashboard URL you use to the redirect allow list, including local development when needed. The dashboard sends reset links back to its current URL, so no production hostname is hardcoded. For production delivery, configure custom SMTP under Authentication → Email. Then test “Forgot password?” end to end, including an expired link.
cd dashboard
cp .env.example .env.production
cp .env.example .env.development
Both files carry the same three values:
VITE_SUPABASE_URL=https://YOUR_PROJECT.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key_here
VITE_DEFAULT_SITE=my-site
VITE_DEFAULT_SITE must match the siteId from step 4. Then build:
npm ci
npm run build
The "chunks larger than 500 kB" warning is cosmetic. Deploy the dist/ folder to any static host: drag-and-drop at app.netlify.com/drop, run npx vercel --prod, or copy dist/* to your document root. For local testing, npm run dev serves it at localhost:5173.
Open the dashboard URL and sign in with the user from step 5. In another tab, visit your site and click around. Wait about 30 seconds, refresh the dashboard: the Sessions and Page Views KPIs should both show at least 1.
If something doesn't show up, the troubleshooting page covers the usual suspects, and docs/QA.md has a full per-event-type verification script.