Sentry.io integration. Vince integration. Region-scoped consent (denied-by-default in EU/EEA/UK/CH, granted elsewhere, DPDP-friendly notice)
107 lines
6.9 KiB
Markdown
107 lines
6.9 KiB
Markdown
# Analytics Setup — mozimo.in
|
|
|
|
The site ships with a layered, code-complete analytics stack. This document
|
|
covers the dashboards you must create and the steps only you can do; after
|
|
them, everything works with no further code changes.
|
|
|
|
```
|
|
Visitor browser
|
|
├─ gtag.js (GA4) ───────────────► GA4 property (consent-mode v2 gated)
|
|
├─ /stats/js/script.js ─┐
|
|
└─ events /stats/api/event ── Caddy ──► Vince container (first-party)
|
|
Server (SSR) ── errors ──────────► Sentry
|
|
Shopify (shop.mozimo.in) ─ purchase/checkout ──► same GA4 property
|
|
```
|
|
|
|
## 1. What is already wired in code
|
|
|
|
| Layer | Implementation |
|
|
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| GA4 | Direct `gtag.js` injected in `src/app/__root.tsx` head scripts (production only, when `VITE_GA4_MEASUREMENT_ID` is set at build). `send_page_view: false` + `PageViewTracker` = exactly one `page_view` per navigation. Cross-domain linker to `shop.mozimo.in`. |
|
|
| Consent | Google Consent Mode v2: denied-by-default in EU/EEA/UK/CH, granted elsewhere. `ConsentBanner` shows only to those visitors (timezone-detected, cookie-stored choice, `/privacy` explains everything). |
|
|
| First-party layer | Vince (Plausible protocol), self-hosted via `ansible/roles/analytics`, proxied same-origin at `/stats/*` by Caddy — survives ad blockers, needs no consent. |
|
|
| E-commerce events | `view_item_list`, `select_item`, `view_item`, `begin_checkout`, `search`, `generate_lead` (forms — no PII), `click`/`contact` (all outbound/tel/mailto links via `src/components/Link.tsx`), `video_start`, `page_not_found`, `web_vitals`. **`purchase` is NOT hand-coded** — Shopify reports it (step 2.2). |
|
|
| Errors | Sentry client + server (custom entries `src/client.tsx` / `src/server.ts`), off unless DSN set. |
|
|
|
|
## 2. One-time dashboards (manual)
|
|
|
|
### 2.1 GA4 property
|
|
|
|
1. analytics.google.com → Admin → **Create property** (`mozimo.in`),
|
|
currency **INR**, timezone **India**.
|
|
2. Add a **Web** data stream for `https://mozimo.in` → copy the
|
|
Measurement ID (`G-…`).
|
|
3. Put it in your local `.env` as `VITE_GA4_MEASUREMENT_ID=G-…`
|
|
(it is baked into the bundle at `docker build` by the Makefile).
|
|
4. Data retention: Admin → Data settings → set **14 months**.
|
|
5. Data filters: add your office IP as **Internal Traffic** (defined filter).
|
|
6. Cross-domain: Data stream → Configure tag settings → **Configure your
|
|
domains** → add `shop.mozimo.in`.
|
|
7. Mark **key events**: `generate_lead`, `begin_checkout` (Admin → Events).
|
|
8. Register **custom definitions** (dimensions): `web_vitals_metric`,
|
|
`web_vitals_rating`, `lead_type`, `lead_topic`, `lead_budget`,
|
|
`search_term` (dimension), `result_count`, `link_domain`, `video_title`.
|
|
9. Admin → Product links → **Search Console** → link the existing property
|
|
(site verification meta is already in `__root.tsx`).
|
|
|
|
### 2.2 Shopify → GA4 (this is what makes purchases visible)
|
|
|
|
1. Shopify Admin → Settings → Apps → **Google & YouTube** channel → install.
|
|
2. Connect the same Google account and select the GA4 property from 2.1.
|
|
3. Shopify then injects the Google tag on `shop.mozimo.in` (storefront +
|
|
checkout) and reports `purchase`/`begin_checkout`/`add_to_cart` into the
|
|
property. The cross-domain linker on both sides stitches sessions —
|
|
verify a `_gl=` parameter appears when clicking _Order this_ on a
|
|
product page.
|
|
4. Place one real (then refunded) test order and confirm `purchase` in
|
|
GA4 Realtime/DebugView.
|
|
|
|
### 2.3 Sentry
|
|
|
|
1. sentry.io → create project **mozimo-web** (platform: TanStack Start /
|
|
JavaScript).
|
|
2. Copy the DSN into your local `.env` (`VITE_SENTRY_DSN`) **and** into
|
|
`ansible/files/.env` (`SENTRY_DSN`) — client needs it at build, server at
|
|
runtime.
|
|
3. Optional sourcemap upload (better stack traces): put `SENTRY_AUTH_TOKEN`,
|
|
`SENTRY_ORG`, `SENTRY_PROJECT` in the build machine env. Builds without
|
|
them skip Sentry's vite plugin entirely.
|
|
4. Verify: visit any page with `?sentry-test=1`… simplest check is a thrown
|
|
error in devtools; a visible page_view + the event landing in Sentry is
|
|
enough for sign-off.
|
|
|
|
### 2.4 Vince (first-party layer)
|
|
|
|
1. `./deploy.sh` once (the playbook creates the container + Caddy route).
|
|
2. Open `https://<www_host>/stats/` → register the admin account (first
|
|
visit only). Then **Add a website** with domain `mozimo.in`.
|
|
3. Set `VITE_PLAUSIBLE_DOMAIN=mozimo.in` in your local `.env` and redeploy —
|
|
the script tag is injected only when this is set.
|
|
4. Check `https://<www_host>/stats/js/script.js` returns the script (200)
|
|
and that browsing the site populates the dashboard within seconds.
|
|
5. With uBlock Origin enabled: visits still appear in Vince but not GA4 —
|
|
expected and exactly why this layer exists.
|
|
|
|
## 3. Verifying GA4 events (DebugView)
|
|
|
|
Append `?debug_mode=1`… simpler: build with `VITE_GA4_DEBUG=1` in `.env`
|
|
temporarily — every event then carries `debug_mode: true` and appears in
|
|
GA4 Admin → DebugView (with the Tag Assistant Companion extension).
|
|
|
|
Walk-through: home (page_view, view_item_list _The Mozimo Edit_) →
|
|
/chocolate → /collections/bars (view_item_list) → a product (view_item) →
|
|
_Order this_ (begin_checkout + outbound click with `_gl`) → /contact
|
|
submit (generate_lead) → search overlay (`search`).
|
|
|
|
## 4. Operational notes
|
|
|
|
- **Dev is always excluded** — analytics scripts only inject in production
|
|
builds.
|
|
- **Disabling a tool** = leaving its env var empty. Nothing breaks.
|
|
- **Changing the GA4 property** = change the env var and redeploy.
|
|
- Sitemap (`dist/client/sitemap.xml` from `scripts/generate-sitemap.mjs`)
|
|
and `robots.txt` are live for Search Console; submit the sitemap once in
|
|
Search Console → Sitemaps.
|
|
- Phase 2 (in-container cart) should add `add_to_cart`, `view_cart`,
|
|
`remove_from_cart` via the same helpers in `src/lib/analytics.ts`.
|