Product analytics and campaign attribution
Configure PostHog, Meta Pixel, Google Analytics, and UTM capture for marketing links and checkout attribution on OpenQuok.
Connect your agent today
Draft from chat, review in your calendar, and publish only what you approve.
Overview
The web app records product analytics (usage and conversion events) and first-touch campaign data from query parameters. Attribution runs in the browser via UtmAttribution.svelte on the root layout; no extra page wiring is required for basic UTM storage.
This is separate from platform analytics (followers, impressions, per-post metrics from social providers). See Analytics APIs for channel and post insights.
Environment variables
Web (web/.env.production.local or development local)
| Variable | Purpose |
|---|---|
| VITE_PUBLIC_POSTHOG_KEY | PostHog project token (phc_…) |
| VITE_PUBLIC_POSTHOG_HOST | PostHog ingest host (e.g. https://us.i.posthog.com) |
| VITE_PUBLIC_FACEBOOK_PIXEL | Meta Pixel ID for browser fbq |
| VITE_PUBLIC_GOOGLE_ANALYTICS_MEASUREMENT_ID | Google Analytics measurement ID (G-…) |
| VITE_PUBLIC_STRIPE_PUBLISHABLE_KEY | When empty, PostHog product events are skipped (self-hosted without billing) |
Backend (backend/.env.production.local or development local)
| Variable | Purpose |
|---|---|
| FACEBOOK_PIXEL_ID | Same numeric Pixel ID as VITE_PUBLIC_FACEBOOK_PIXEL |
| FACEBOOK_PIXEL_ACCESS_TOKEN | Meta Conversions API access token (server only; never expose in the web app) |
Note
PostHog and Meta are optional. Leave keys empty for local dev or self-hosted installs that do not run paid checkout or ad attribution.
More detail on Vite keys: Configuration — Vite (SvelteKit).
Where to get credentials
- PostHog — posthog.com → Project settings → Project token (
phc_…) and API host. - Meta Pixel — Meta Events Manager → your Pixel → Pixel ID; Conversions API → Generate access token (backend only).
- Google Analytics — Google Analytics → Admin → Data streams → Measurement ID.
UTM and campaign capture
On every visit, the app can persist:
localStorage key | Set when | Meaning |
|---|---|---|
utm | First matching query param | Campaign source string (first-touch) |
landingUrl | First visit only | Full URL of the first page loaded |
referrer | First visit only | document.referrer on that first visit |
Supported query parameters
The first non-empty value wins and is stored once (later visits do not overwrite utm):
- utm_source
- utm
- ref
Example marketing links
Newsletter
https://www.openquok.com/sign-up?utm_source=newsletter&utm_medium=email&utm_campaign=march Stored value: newsletter (only utm_source is read into utm; medium and campaign are not saved unless you extend utm.ts).
Partner or affiliate
https://www.openquok.com/?ref=partner_acme Stored value: partner_acme.
Paid social
https://www.openquok.com/?utm_source=meta&utm_campaign=prospecting Stored value: meta.
Verify in the browser
- Open your site with a tagged URL, e.g.
https://localhost:5173/?utm_source=test_dev. - DevTools → Application → Local Storage → your origin.
- Confirm
utm,landingUrl, andreferrer. - Navigate to another route without query params —
utmshould still betest_dev.
Post-checkout return (check)
If the user lands with ?check=1 (or any truthy check query), the layout fires:
- PostHog event
purchase(when Stripe + PostHog are configured) - Meta conversion
StartTrial(when Pixel + CAPI token are configured)
Example:
https://www.openquok.com/account/billing?check=1 Use this on return URLs after Stripe Checkout or trial confirmation flows you control.
Reading stored UTM in app code
Export readStoredUtm() from $lib/product-analytics returns the stored campaign string. You can attach it to checkout payloads or analytics event properties, for example:
import { readStoredUtm, fireProductEvent } from '$lib/product-analytics';
const utm = readStoredUtm();
fireProductEvent('initiate_checkout', { utm }); Tip
Subscribe and Stripe Checkout in the current app do not yet send utm to the API automatically. Wire readStoredUtm() into your billing flow when you want server-side or Stripe metadata attribution.
Event map (hosted product)
When billing is enabled (VITE_PUBLIC_STRIPE_PUBLISHABLE_KEY set), common events include:
| User action | PostHog (approx.) | Meta conversion |
|---|---|---|
| Sign-up success | register | CompleteRegistration |
| Subscribe click | — | InitiateCheckout |
Checkout return with check | purchase | StartTrial |
| Billing poll after checkout | purchase | Purchase |
Channel connected (added query) | channel_added | — |