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
10 changes: 10 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ jobs:
working-directory: scripts
run: npm test

- name: Validate analytics contract
run: node scripts/check-analytics.mjs

# We deliberately do NOT run `npm install` on each template in CI:
# contributors install locally before opening a PR, package-lock.json
# makes the install reproducible, and the slow per-template install
# would dominate CI time as the registry grows. The static checks below
# (JSON parse, file existence, secret patterns, SQL parse, edge-function
# tsc) cover what install would catch except the rare "package was
# yanked from npm" case — we'll catch that via Dependabot/Snyk later.
edge-function-tsc:
name: tsc --noEmit on edge functions
runs-on: ubuntu-latest
Expand Down
49 changes: 49 additions & 0 deletions ANALYTICS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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.

## Runtime configuration

The platform serves `/.well-known/insforge-runtime-config.js`; every template loads it synchronously
before the application bundle so it can inject `window.__INSFORGE_RUNTIME_CONFIG__`:

```ts
{
posthogHost: 'https://us.i.posthog.com',
posthogProjectToken: 'phc_...',
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.

## 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.

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.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +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)
- 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
10 changes: 10 additions & 0 deletions admin-dashboard/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,12 @@
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_INSFORGE_APP_ID=
VITE_INSFORGE_ENVIRONMENT_ID=
VITE_INSFORGE_TEMPLATE_ID=admin-dashboard
VITE_INSFORGE_TEMPLATE_VERSION_ID=
VITE_INSFORGE_RELEASE_ID=
2 changes: 1 addition & 1 deletion admin-dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</head>
<body>
<div id="root"></div>
<script src="/.well-known/insforge-runtime-config.js"></script>
<script vite-ignore src="/.well-known/insforge-runtime-config.js"></script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
129 changes: 129 additions & 0 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: 1 addition & 0 deletions admin-dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"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