Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 30 additions & 22 deletions ANALYTICS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Platform-managed analytics contract

Every official template ships with PostHog analytics enabled for production builds. InsForge creates
one PostHog project per application and injects the public project token at runtime. Template users
do not create a PostHog account and templates must never contain a `phx_` personal API key.
Every official template ships with Google Analytics 4 (GA4) enabled for production builds.
InsForge creates one GA4 property and web data stream per application, then injects its public
measurement ID at runtime. Template users do not need to create a Google Analytics account, and
templates must never contain Google service-account credentials or a Measurement Protocol API
secret.

## Runtime configuration

Expand All @@ -11,39 +13,45 @@ before the application bundle so it can inject `window.__INSFORGE_RUNTIME_CONFIG

```ts
{
posthogHost: 'https://us.i.posthog.com',
posthogProjectToken: 'phc_...',
gaMeasurementId: 'G-XXXXXXXXXX',
applicationId: '...',
environmentId: '...',
templateVersionId: '...',
releaseId: '...'
}
```

The analytics helper prefers this object and falls back to the documented `NEXT_PUBLIC_*` or
`VITE_*` variables for standalone deployments. Missing configuration and non-production builds are
safe no-ops.
The analytics helper prefers this object and falls back to `NEXT_PUBLIC_GA_MEASUREMENT_ID` or
`VITE_GA_MEASUREMENT_ID` for standalone deployments. Missing configuration and non-production
builds are safe no-ops. A measurement ID is public; Google credentials remain platform-only.

## Event rules

Import `analytics` from the template's `lib/analytics` module. Use its semantic helpers when they
fit, or `analytics.track('domain_event', { safe_property: value })`. Conversion events must fire
only after the operation succeeds; payments must include their stable transaction ID.

Every template automatically captures page views, page leaves, and web performance measurements.
The helper also provides `cta_clicked`, `form_started`, `form_submitted`, `sign_up_completed`,
`login_completed`, and `purchase_completed`, but templates must wire those semantic events into
their own successful business operations. Every event is registered with application,
environment, template-version, and release context.
Every template sends an initial `page_view` and another privacy-safe page view when a Next.js or
Vite SPA route changes. Page locations contain only origin and pathname; query strings and URL
fragments are never sent. The platform disables enhanced measurement's automatic browser-history
page changes on managed streams, preventing these manual SPA page views from being counted twice.
The semantic helpers emit GA4-compatible events: `cta_click`, `form_start`, `form_submit`,
`generate_lead`, `sign_up`, `login`, and `purchase`. `formSubmitted` is an ordinary completed form;
use `leadSubmitted` only for an actual sales/contact lead because `generate_lead` is a Key Event.
Legacy event names passed to `track` are mapped to the corresponding non-conversion or recommended
event names. Every event also
receives application, environment, template-version, and release context through the shared GA4
event context.

Never send names, emails, phone numbers, addresses, credentials, access tokens, form bodies,
prompts, message text, filenames, or raw URLs containing query parameters. `identify` accepts only
the application's opaque user ID and no person properties. The helper drops common PII property
keys and email-shaped values as a final guard, but this does not replace careful event design.

Session replay defaults to a stable 10% per-session sample, masks all inputs and personal-data
properties, and masks/blocks elements marked
`data-private`. Add `data-private` to any region that renders customer content. Autocapture is off,
so product events remain stable when markup or copy changes.

Run `node scripts/check-analytics.mjs` before publishing a template.
the application's opaque user ID and no user properties. The helper drops common PII property keys
and email-shaped values as a final guard, but this does not replace careful event design.
For privacy-first behavior, keys containing a delimited `name`, `content`, or `query` token are also
blocked (for example `template_name`, `content_type`, and `query_length`), even when a particular
value would not contain PII.

GA4 does not provide session replay, and official templates do not load a replay SDK or capture DOM
content. Google's tag host may be unavailable from mainland China; deployments targeting mainland
users must validate outbound reachability and should expect zero events when it is blocked. Run
`node scripts/check-analytics.mjs` before publishing a template.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Not standalone templates. These are scaffolds the CLI overlays on top of an exis
- Framework starters and app templates built with [Next.js](https://nextjs.org), [React](https://react.dev), and [Vite](https://vite.dev)
- UI foundations built with [Tailwind CSS](https://tailwindcss.com) across the repository
- Authentication, database, and storage integration with [InsForge](https://insforge.dev)
- Platform-managed PostHog analytics with a shared [event and privacy contract](./ANALYTICS.md)
- Platform-managed GA4 analytics with a shared [event and privacy contract](./ANALYTICS.md)
- Per-template setup guides and example environment variables for local development
- Deployment paths designed to work well with [Vercel](https://vercel.com)
- Templates designed to be adapted into real products
Expand Down
4 changes: 1 addition & 3 deletions admin-dashboard/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ VITE_INSFORGE_URL=https://your-appkey.region.insforge.app
VITE_INSFORGE_ANON_KEY=your-anon-key

# Platform-managed analytics (production only)
VITE_POSTHOG_PROJECT_TOKEN=phc_project_token
VITE_POSTHOG_HOST=https://us.i.posthog.com
VITE_POSTHOG_REPLAY_SAMPLE_RATE=0.1
VITE_GA_MEASUREMENT_ID=
VITE_INSFORGE_APP_ID=
VITE_INSFORGE_ENVIRONMENT_ID=
VITE_INSFORGE_TEMPLATE_ID=admin-dashboard
Expand Down
129 changes: 0 additions & 129 deletions admin-dashboard/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion admin-dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"input-otp": "^1.4.2",
"lucide-react": "^0.474.0",
"next-themes": "^0.4.6",
"posthog-js": "^1.425.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-hook-form": "^7.76.1",
Expand Down
Loading
Loading