Vibe coding best practices for analytics | Orwel
Best practices Updated October 21, 2026

Vibe coding best practices for analytics

Give the coding agent rules before it writes tracking code, keep the key in an environment variable, test with a development key in Dev mode, use catalog event codes, identify users with their email and await every conversion. Most broken vibe coded analytics comes from skipping one of these.

Orwel is an event analytics SDK for startups, developers and vibe coders that maps feature adoption and conversion funnels, and feeds the results back to AI agents through MCP.

Why this checklist exists

A coding agent can instrument an app in a minute, and left alone it makes the same mistakes every time: invented event names, events on clicks instead of on success, a hardcoded key, a form that says "thanks" before the conversion was sent.

These are the rules we give agents for Orwel. They are the measure step of vibe coding, done so the numbers can be trusted when you feed them back to the agent.

Prompts and rules

Do give the agent the rules before the first tracking call. Install the skill with npx skills add hyperlabs-ai/hyper-skills/orwel, or paste the CLAUDE.md analytics template into your project instructions. Rules in context beat corrections after the fact.

Do describe what you want to learn, not which calls to write. "Measure how many signups create a first project" gives the agent room to find the right place in the code. The vibe coding prompts library has ten examples.

Do ask the agent to propose the event list first and confirm it before instrumenting. A table of code, where it fires and its properties takes a minute to review and saves a rewrite.

Don't let the agent sprinkle tracking across components. One call site per business action, in the service or data layer where the action succeeds.

Keys and environments

Do read the key from an environment variable with the name your framework expects: NEXT_PUBLIC_ORWEL_KEY in Next.js, PUBLIC_ORWEL_KEY in SvelteKit and Astro, VITE_ORWEL_KEY in Vite. Add an empty line to .env.example and keep .env in .gitignore.

Do use the development key (orwel_dev_...) locally and in staging, and the production key (orwel_pk_...) only in production. Leads created with the development key are marked as test, and no notification emails or integrations run.

Don't put an API key (orwel_sk_...) in browser code or in orwel.init(). That key reads data. It belongs in server code and in your MCP client config, never in the bundle.

Don't forget the hosting provider. .env is not deployed; add the variable in your host's environment settings before you ship.

Event names

Do use codes from the catalog for track(). Orwel's catalog has 257 ready codes such as signup, login, onboarding_completed, project_created, invite_sent, file_uploaded and purchase. Codes are lowercase snake_case, up to 50 characters.

Do register custom codes before you ship code that sends them. Add them to a journey or feature in Journeys setup or Features setup in the dashboard and save; from then on the ingest accepts them.

Don't let the agent invent codes like button_click or project_click. An unknown code is rejected with event_not_found, and the SDK does not retry it. In a mixed batch the server answers 207 and the browser console stays quiet, so you only see it in Dev mode.

Don't build funnels from page views and clicks. Journey milestones count in any order within the period, so pick actions that only happen as real progress.

Identify

Do call orwel.identify({ email }) when a user signs in or signs up, with the name and company if you have them. Without an email the visitor stays anonymous and Dev mode shows an identify_no_email warning.

Do identify right before a lead conversion on forms, so the lead is tied to the visitor and their session history.

Conversions

Do await orwel.conversion('<code>', { email, ...data }) in the submit handler, before you redirect, show the success message or unmount the form. Since SDK 1.6 it returns { success, reason }.

Do include an email in every lead conversion. Without one the conversion is recorded, but it is not enriched, no notification email goes out and CRM integrations skip it.

Do add amount (a number) and currency (an ISO code like USD) to purchases and payments.

Do guard the handler against double submits with a loading flag, and wrap the analytics call in try/catch so it can never block the user's submit.

Don't combine orwel.form() with a manual conversion on the same form. Every submit counts twice, and frameworks that replace the form with a success state can log a false form_abandon.

Don't also track() the same code you send as a conversion. Conversion codes are free-form; track codes are checked against the catalog.

Verify before you ship

Do run the app with the development key and debug: true, then trigger one of each: a page load, an identify, a track with every custom code and one conversion with an email.

Do open Dev mode and check every request. Errors mean rejected (event_not_found, invalid_field, missing_session_id). Warnings mean accepted but harmful (conversion_no_email, missing_attribution, sdk_outdated). The only note you should see is test_mode_integrations_skipped.

Do test attribution with ?utm_source=test in the URL. Without UTMs or a click id the lead counts as direct.

Don't trust the browser console as proof. Debug logs can show an event as tracked even when the server rejects it later. The HTTP status and Dev mode are the proof.

Don't swap to the production key until Dev mode is clean.

After launch

Do close the vibe coding feedback loop. Connect the Orwel MCP server to your agent and ask it to check conversions and detected issues before you plan the next change. Change one thing per cycle so the next measurement tells you what moved.

Why Orwel

One plan

49 USD a month, 2 USD less every paid month down to 35 USD, or 420 USD a year

No caps

Unlimited leads and visitors under fair use

2-minute install

One script or npm package, or ask your coding agent to do it

MCP server

Claude, Cursor or your own agent read real usage before the next prompt

Semantic catalog

257 ready events, so tracking is named the same in every project

Dev mode

A live debugger and development keys that keep tests out of real data

FAQ

What is the most common analytics mistake in vibe coding?

Invented event names. The agent writes track('signup_button_click'), the code is not in the catalog and the event is rejected. Use catalog codes or register custom ones first.

Should I use the development key or the production key while building?

The development key. It runs through the same pipeline, every request shows up in Dev mode with errors and warnings, leads are marked as test and no emails or integrations run. Switch to the production key in the production environment only.

Why must conversions be awaited?

If the form unmounts or the page redirects before the conversion is sent, it can be lost. Awaiting orwel.conversion() waits for the visitor id, sends the conversion and returns whether it was delivered.

Is the Orwel key safe in the browser?

The production key can send events but not read data, so it can live in the client bundle. Still read it from an environment variable so each environment uses its own key. Never put an orwel_sk_ API key in browser code.

How do I check that everything works?

Run the app with the development key, trigger each event once and open Dev mode. Every request should be accepted with no errors.

Keep reading

See what users do with what you shipped

Install in 2 minutes. 14-day free trial, one plan with everything.