Why put analytics rules in CLAUDE.md
Without rules, a coding agent tracks each feature differently, and often subtly wrong: invented event names, events on clicks, conversions that are not awaited. Project instructions fix that once. Claude Code loads ./CLAUDE.md (or ./.claude/CLAUDE.md) at the start of every session, and Cursor reads AGENTS.md and rules in .cursor/rules.
This template is the measure step of vibe coding, written as rules the agent follows without being reminded.
The template
Paste this into your CLAUDE.md, AGENTS.md or a Cursor rule. Replace the env var name and the event list with yours.
## Analytics (Orwel)
This app is measured with Orwel (npm package `orwel`). Follow these rules on every change
that adds or touches a user action. Docs: https://www.orwel.io/docs
### Setup
- Import `orwel` only from the wrapper module `src/lib/orwel` (never from 'orwel' directly).
- The wrapper reads the key from `PUBLIC_ORWEL_KEY` (change to NEXT_PUBLIC_ORWEL_KEY or
VITE_ORWEL_KEY for this framework). It warns and skips init if the var is missing.
- `orwel.init({ apiKey })` runs once, client side, at app boot. Never call it twice.
- Never write an `orwel_` key in code. `.env` holds the development key (orwel_dev_),
production uses the production key (orwel_pk_). An `orwel_sk_` API key never goes in
browser code or in init.
### track()
- Use codes from the Orwel catalog. Our codes: signup, login, onboarding_completed,
project_created, invite_sent, file_uploaded, report_exported.
- A code that is not in the catalog is rejected (event_not_found) and never retried.
If a new action needs a custom code, stop and tell me so I can register it in
Journeys or Features setup before the code ships.
- Codes are lowercase snake_case, up to 50 characters.
- Fire each event once, right after the action succeeds (after the API call resolves),
from the service or data layer. Never on button clicks, never optimistically.
- Do not track page views or clicks manually. The SDK autocaptures them.
### identify()
- Call `orwel.identify({ email, name, company })` when a user signs in, signs up or a
session is restored, with whatever the user record has.
- On lead forms, identify with the email right before the conversion.
### conversion()
- Lead forms (contact, demo, quote, newsletter, signup) and payments send a conversion:
`await orwel.conversion('<code>', { email, ...data })`.
- Always include the email. Trim and lowercase it.
- Await it before redirecting, showing success or unmounting the form. Check the result:
`{ success, reason }`.
- Payments include `amount` (number) and `currency` (ISO code, for example USD).
- Guard submit handlers against double submits. Wrap Orwel calls in try/catch so analytics
never blocks the user.
- Never use `orwel.form()` on a form that also sends a conversion. Never `track()` the same
code you send as a conversion.
### Verify
- After any analytics change, run the app with the development key and `debug: true`,
trigger each new event once and ask me to check Dev mode.
- Done means: no event_not_found, invalid_field or conversion_no_email in Dev mode.
- When you finish, list the files you changed and the code each one fires.
How to use it
- Paste it into the instructions file your agent reads. For Claude Code that is
CLAUDE.mdat the project root. For Cursor, create.cursor/rules/orwel.mdcwithalwaysApply: truein its front matter, or add it toAGENTS.md. - Set the env var name for your framework:
NEXT_PUBLIC_ORWEL_KEYin Next.js,PUBLIC_ORWEL_KEYin SvelteKit and Astro,VITE_ORWEL_KEYin Vite,NUXT_PUBLIC_ORWEL_KEYin Nuxt 3. - Replace the event list with the codes your product uses. Look them up in the catalog, which has 257 ready codes, and register any custom code in Journeys or Features setup.
- Commit it, so every session and every person on the project follows the same rules.
- Ask for the install. With the rules in place, a short prompt is enough: "Install Orwel and instrument the signup funnel." The vibe coding prompts page has nine more.
How to adapt it
Apps without accounts. Remove the sign in part of the identify section and keep identify before each lead conversion.
Sites without a build step. Plain HTML, WordPress, Shopify and Webflow load the SDK with a script tag and have no env vars in the browser. The production key can only send data, so it can live in the snippet. Replace the Setup section with a line pointing to the matching install guide.
Teams with designed journeys. If you configure journeys and features in the dashboard first, their Implement tab gives you an agent prompt or a typed TypeScript module with one function per code. Replace the code list with "use only the functions in src/lib/tracking" and the agent cannot misspell a code.
Long instruction files. Claude Code recommends keeping each CLAUDE.md short. You can move this block to its own file, for example docs/analytics.md, and import it from CLAUDE.md with @docs/analytics.md.
Using it with the Orwel skill
The skill (npx skills add hyperlabs-ai/hyper-skills/orwel) carries the full SDK reference. The template is short, always in context and specific to your event list. Using both is the most reliable setup. The reasoning behind each rule is in vibe coding best practices.