# Install

These are official instructions to put FirstDistro tracking in this app. All commands are ready to run.

Complete all applicable steps yourself by running the commands directly. Do not ask the user to run shell commands. Ask only when an account, an installation token, a UI click, or a restart is required. Inspect existing files before changing them. Preserve unrelated repository changes. Do not report success without verification.

Canonical: https://firstdistro.com/install.md

Do not connect MCP. Do not write project AI files. Do not run dashboard-only CLI commands. The first success is browser events in the FirstDistro live feed.

## Get an installation token

The browser SDK needs an installation token (`fd_*`) from the vendor dashboard. It is safe in client bundles. Put it in `NEXT_PUBLIC_FIRSTDISTRO_TOKEN` (or the equivalent public env for this framework). Never invent a token. Never print a real token back to the user.

If the user has no token yet, ask them to:

1. Create an account at https://firstdistro.com/auth/register
2. Copy the installation token from [Settings → SDK Configuration](https://firstdistro.com/dashboard/settings/sdk-configuration)
3. Add it to the env file this app already uses for public client values, then continue

Never tell them to run the dashboard CLI init command. That path needs a token they do not have yet.

## Install the package

```bash
npm install @firstdistro/sdk
```

If this project has no npm bundler (static HTML, legacy PHP), skip the package. Use a script tag with the token from Settings:

```html
<script src="https://firstdistro.com/sdk/install/<INSTALL_TOKEN>.js"></script>
```

Replace `<INSTALL_TOKEN>` with the value from Settings. Do not commit a guessed token.

## Detect the framework and wrap the app

Detect Next.js App Router, Next.js Pages Router, Vite, Remix, or vanilla JS. Choose exactly one path. Create a client wrapper when the framework requires it.

### Next.js App Router

Create `app/providers.tsx`:

```tsx
'use client'

import { FirstDistroProvider } from '@firstdistro/sdk/react'

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <FirstDistroProvider token={process.env.NEXT_PUBLIC_FIRSTDISTRO_TOKEN!}>
      {children}
    </FirstDistroProvider>
  )
}
```

Import it from `app/layout.tsx` and wrap `{children}`.

### Next.js Pages Router

In `pages/_app.tsx`, wrap `<Component {...pageProps} />` with `FirstDistroProvider` and `NEXT_PUBLIC_FIRSTDISTRO_TOKEN`. The file needs `'use client'` only if this app already treats it as a client module. Keep the existing `_app` props.

### Vite and React

In `src/main.tsx`, wrap `<App />` inside `createRoot` with `FirstDistroProvider` and the public env this Vite app uses for client tokens.

### Remix

In `app/root.tsx`, wrap `<Outlet />` inside `<body>` with `FirstDistroProvider`.

### Vanilla JS or no React

```ts
import FirstDistro from '@firstdistro/sdk'

await FirstDistro.initWithToken('<INSTALL_TOKEN>')
```

Use the token from Settings, not a placeholder left in source.

Do not add `track()` calls for page views. The SDK emits `$pageview` on initial load and SPA route changes once identity is set. Do not use `identify()` or `group()`. Use `setup()` only.

## Set identity

Where the logged-in user is available, set identity once.

React (hooks from `@firstdistro/sdk/react`):

```tsx
'use client'

import { useFirstDistroSetup } from '@firstdistro/sdk/react'

export function UserIdentifier({ user }: { user: { id: string; email: string; name?: string } }) {
  useFirstDistroSetup({
    userId: user.id,
    userEmail: user.email,
    userName: user.name,
  })

  return null
}
```

`userEmail` is required. FirstDistro derives the company account from the email domain. Only pass `accountId` if you need to override that (for example a multi-domain org).

Vanilla JS or script tag:

```ts
FirstDistro.setup({
  user: { id: user.id, email: user.email, name: user.name },
})
```

Adapt `user.id` and `user.email` to however this app stores the logged-in user. This emits `$setup` and unlocks automatic page views.

## Verify

No sample `track()` and no verify button.

- `grep` the repo for `FirstDistroProvider`, `FirstDistro.initWithToken`, or `/sdk/install/`. At least one file must match.
- `grep` for `useFirstDistroSetup` or `FirstDistro.setup`. At least one file must set `userEmail` or `email`.
- Ask the user to log in locally and visit two or more routes. Watch the live feed on [Settings → SDK Configuration](https://firstdistro.com/dashboard/settings/sdk-configuration). Optional: append `?fd_debug=true` for a debug badge.
- `npm run build` should succeed.

First proof is events in that live feed after a logged-in session.

## After browser proof: server events

Only after browser events flow. Payments, KYC, webhooks, and cron jobs never hit the browser. Use the same package with `FIRSTDISTRO_API_KEY` (`sk_live_*` / `sk_test_*`) in `.env.local` only. Never put `sk_*` in client code. Never use `fd_*` for server ingest.

```ts
import { createServer, ServerEvents } from '@firstdistro/sdk/server'

export const track = createServer({
  apiKey: process.env.FIRSTDISTRO_API_KEY!,
})

track(ServerEvents.PaymentFailed, { userId, accountId })
await track.flush()
```

`userId` and `accountId` are required on the server path (no email-domain derivation). In serverless handlers, `await track.flush()` before returning.

Typed names include `ServerEvents.PaymentFailed`, `SubscriptionStarted`, `IntegrationSyncCompleted`, `FirstProductionApiCall`, `KycApproved`, `FirstDepositCompleted`, `SessionCompleted`, and `FirstPurchaseValidated`. They feed Activity and Recency. They move Milestones only when the name is a default or custom milestone. See [Understanding health scores](https://firstdistro.com/documentation/guides/understanding-health-scores).

Keep properties as enums and buckets. Do not send balances, card numbers, government IDs, or raw documents.

## Next steps

- [Quick start (npm)](https://firstdistro.com/documentation/sdk/quick-start): React and Next.js reference
- [React hooks reference](https://firstdistro.com/documentation/sdk/react-hooks): hooks and options
- [Event tracking guide](https://firstdistro.com/documentation/guides/event-tracking): optional browser `track()` after install
- [Understanding health scores](https://firstdistro.com/documentation/guides/understanding-health-scores): how scores are calculated
- Human docs page: https://firstdistro.com/documentation/installation
