Analytics
Configure Google Analytics 4 and OpenPanel, then track only key funnel events
Analytics
EasyStarter Web ships with two optional analytics providers. Both are skipped automatically when their environment variables are empty:
| Provider | Purpose |
|---|---|
| Google Analytics 4 | Traffic, conversion funnels, audience reports |
| OpenPanel | Open-source, privacy-friendly product analytics (events, retention, funnels) |
You can enable either, both, or neither — leave the variable blank to disable.
Track only the key funnel events by default: signup completed, login succeeded, subscription started, core generation finished, submission created, and similar conversion points. The template keeps GA4 page views enabled, but OpenPanel does not automatically track every route change so free-tier usage is not spent on low-signal navigation events.
Google Analytics 4
Create a GA4 property and grab the Measurement ID
Official docs: Find your Google tag / Measurement ID
- Visit analytics.google.com and sign in
- Open Admin → Create → Property, fill in product name, time zone, currency
- Inside the new property, pick Data Streams → Add stream → Web
- Enter the site URL (e.g.
https://yourdomain.com) and create the stream - Copy the Measurement ID shown on the stream detail page — format
G-XXXXXXXXXX
Set environment variables
Local development (apps/web/.env.development):
VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXXLocal production deploy (vars block of apps/web/wrangler.jsonc, plain text — not a Secret):
{
"vars": {
"VITE_GA_MEASUREMENT_ID": "G-XXXXXXXXXX",
// ...
}
}CI / remote-deploy variable list (apps/web/.env.production):
Used by local production builds (pnpm build:web:production) and as the canonical list of variables to mirror into Cloudflare's build environment when deploying from GitHub:
VITE_GA_MEASUREMENT_ID=G-XXXXXXXXXX
VITE_-prefixed values end up in the client bundle and aren't sensitive — keep them inwrangler.jsonc/ CI build variables, nopnpm run secrets:bulk:productionneeded..env.productionis gitignored and stays local.
Track key events explicitly
The Web app exposes small tracking helpers. Call them only from conversion points that matter to the product:
import { trackGoogleEvent } from "@/lib/analytics/google-analytics";
import { trackOpenPanelEvent } from "@/lib/analytics/openpanel";
trackGoogleEvent("sign_up", {
method: "google",
});
trackOpenPanelEvent("subscription_started", {
plan: "pro",
});If a route is truly part of the product funnel, record an OpenPanel screen view manually:
import { trackOpenPanelScreenView } from "@/lib/analytics/openpanel";
trackOpenPanelScreenView("/pricing");Do not treat every route transition as a product event. Start with 3-5 key funnel steps, then add more events when the data answers a real product question.
OpenPanel
OpenPanel is an open-source product analytics platform. You can self-host it or use the Cloud version — the free tier is plenty for an indie project. EasyStarter targets the Cloud version by default.
Create an OpenPanel project
Official docs: Web SDK
- Sign up at openpanel.dev
- In the dashboard click Create Project
- Fill in Project name
- Keep Website enabled, and turn off App and Backend / API unless you need them now
- Enter the production site URL in Domain, e.g.
https://yourdomain.com - Add event-ingestion origins under Allowed domains, e.g.
https://yourdomain.com - Click Create project
- After creation, copy the Website Client ID from the project's client details (UUID)
Set environment variables
Local development (apps/web/.env.development):
VITE_OPENPANEL_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxLocal production deploy (apps/web/wrangler.jsonc):
{
"vars": {
"VITE_OPENPANEL_CLIENT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
// ...
}
}VITE_OPENPANEL_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxAlso a public value. For CI deploys, add it to the platform's build variables, not the secrets section.