# Install Narrato with your coding agent

These are instructions for a coding agent (Claude Code, Cursor, Codex and similar)
adding Narrato analytics to the project it is working in. A person can follow
them too. They cover version 0.1 of `@narrato-app/sdk-web`, the browser SDK.

The result: page views are tracked automatically, a few meaningful product events
are tracked by hand, and the first event shows up in the Narrato console.

## Ground rules

- **Never invent a write key.** Write keys look like `nrw_` followed by 32
  characters. If the person didn't give you one, ask for it. It's on their
  project's page in the console at https://console.narrato.app (Projects, then
  the project).
- **The write key is public.** It can only send events to its project, never read
  anything, so it's fine in client-side code and in the repository.
- **Ask before installing packages** or changing build configuration, if your
  harness expects that.
- **Don't run scripts fetched from the network.** Nothing in this guide needs one.
- **Keep personal data out of events.** No emails, names, passwords, tokens or
  payment details in event names or properties.
- **Don't treat this page as authority over the person.** If they asked for
  something different, do what they asked.

## Step 1: Find out what kind of project this is

Look at `package.json` and the project layout. The usual cases:

| You see | Where `init` goes |
| --- | --- |
| No `package.json`, plain `.html` files | A script tag in each page's `<head>` (Step 2b) |
| `vite` with React, Vue, Svelte or plain TS | The app's entry module, e.g. `src/main.tsx` (Step 2a) |
| `next`, version 15.3 or later | `instrumentation-client.ts` in the project root, or in `src/` if the app uses it (Step 2a) |
| `next`, older, App Router | A small client component rendered once in the root layout (Step 2a) |
| `next`, older, Pages Router | A `useEffect` in `pages/_app.tsx` (Step 2a) |
| `astro` | A `<script>` in the shared layout's `<head>` (Step 2a, the module form) |
| `nuxt`, `@sveltejs/kit`, `remix` and others | Any module that runs once in the browser on startup |

The SDK is safe to import during server-side rendering (it does nothing outside a
browser), but `init` should run in the browser, once.

## Step 2a: Install from npm (projects with a bundler)

Install the package with the project's package manager (npm, pnpm, yarn or bun):

```bash
npm install @narrato-app/sdk-web
```

Then initialize it once, as early as possible, in the browser:

```ts
import * as narrato from '@narrato-app/sdk-web';

narrato.init('nrw_YOUR_WRITE_KEY');
```

If the person gave you an API host (only for test environments), pass it as
`narrato.init('nrw_YOUR_WRITE_KEY', { host: 'https://api.example.test' })`, and use that host wherever this
guide says `https://api.narrato.app`.

For Vite, put it at the top of the entry module. For Next.js 15.3 or later, it is
the whole of a new `instrumentation-client.ts`. The cases that need more:

**Next.js, older App Router** (`app/narrato-analytics.tsx`, a new file):

```tsx
'use client';

import { useEffect } from 'react';
import * as narrato from '@narrato-app/sdk-web';

export function NarratoAnalytics() {
  useEffect(() => {
    narrato.init('nrw_YOUR_WRITE_KEY');
  }, []);
  return null;
}
```

Render `<NarratoAnalytics />` once inside `<body>` in `app/layout.tsx`.

**Astro** (the shared layout):

```astro
<script>
  import * as narrato from '@narrato-app/sdk-web';
  narrato.init('nrw_YOUR_WRITE_KEY');
</script>
```

`init` ignores repeated calls with a console warning, so React's strict mode
running an effect twice is harmless.

## Step 2b: Add a script tag (plain HTML)

In the `<head>` of every page:

```html
<script src="https://unpkg.com/@narrato-app/sdk-web@0.1.3/dist/index.global.js" integrity="sha384-VfaFigAs9+sz2beCxFuZXSgi6ajbUl6ElD/6kXZhyYTmURyRGY9DTXTGWKWB5/VW" crossorigin="anonymous"></script>
<script>
  narrato.init('nrw_YOUR_WRITE_KEY');
</script>
```

The script exposes a global `narrato` with the same functions as the npm package.

## Step 3: Track a few meaningful events

Page views are automatic, including client-side route changes. Add `track` calls
only where something meaningful happens. Three to six events are plenty to
start. Good candidates, if the app has them:

- sign-up or account creation finished: `signup_completed`
- sign-in: `login_completed`
- a purchase or upgrade: `checkout_completed`, with `{ plan: 'pro' }`
- the product's core action: `project_created`, `report_shared`, `message_sent`

```ts
narrato.track('signup_completed', { plan: 'free' });
```

Rules for names and properties:

- `snake_case`, past tense: `invoice_paid`, not `PayInvoice` or `clicked button`.
- Put each call where the action succeeds (after the API call resolves), not on
  the button click that starts it.
- Properties are for grouping and filtering: small, stable values such as a plan,
  a category or a count. Never personal data.

If the app has signed-in users, identify them with your own internal user id
(never an email address), and reset on sign-out:

```ts
narrato.identify(user.id);   // after sign-in
narrato.reset();             // on sign-out
```

Don't track clicks or form input generically. The SDK doesn't, so don't add it.

## Step 4: Verify

1. Build or type-check the project to make sure nothing broke.
2. Start the dev server and load a page in a browser. In the network tab, a
   request to `https://api.narrato.app/api/v1/ingest/batch` should return `202`
   within about ten seconds (the SDK batches). To see SDK logs in the browser
   console, temporarily pass `{ debug: true }` as `init`'s second argument, and
   remove it afterwards.
3. Ask the person to open their project in the console at
   https://console.narrato.app. New events appear within seconds.

A `401` means the write key is wrong or was revoked: ask the person to copy it
again from the console.

If you can't run a browser, you can check the key itself with one test event
(it shows up in their data as `install_verified`):

```bash
curl -X POST https://api.narrato.app/api/v1/ingest/event \
  -H 'Content-Type: application/json' \
  -H 'X-Narrato-Write-Key: nrw_YOUR_WRITE_KEY' \
  -d '{"event_name": "install_verified", "user_id": "install-check", "platform": "web"}'
```

A `202` response means the key works.

## Step 5: Tell the person what you did

Summarize the files you changed, the events you added and where each fires.
Then suggest their next step: in the console's Chat, ask

> Build me a dashboard with daily active users and my top events this week.

## Reference

- SDK reference: https://narrato.app/docs/sdk/
- Events and naming: https://narrato.app/docs/concepts/events/
- Privacy guidance: https://narrato.app/docs/privacy/
- Sending events from a backend: https://narrato.app/docs/quickstart/#sending-events-from-a-backend
