# Quickstart: Web (npm) (https://www.getfounderhq.com/docs/analytics/getting-started/quickstart-web-npm)

Install the package, initialize it once, and see your first event in
FounderHQ. About 5 minutes.

<Callout title="Before you start">
You need a FounderHQ account and a publishable key. In the app, open
**Sequences → Settings → Event API keys**, create a key for
**Browser/mobile**, and copy it. The full key is shown only once.
</Callout>

## 1. Install the package

```npm
npm install @founderhq/events
```

## 2. Initialize once, at your app's entry point

```ts
import { founderhq } from "@founderhq/events";

founderhq.init("fhq_pk_XXXX");
```

`founderhq` is a shared client. Import it anywhere. Calling `init` a
second time does nothing, so a hot reload is safe.

From here on, pageviews, page leaves, sessions, clicks, rage clicks,
dead clicks, outbound clicks, scroll depth, and Core Web Vitals are
captured for you. Single-page navigations count as pageviews.

Next.js App Router, or any framework that renders on the server? Put
the call in a client component and render it once in your root layout.

```tsx
"use client";

import { useEffect } from "react";
import { founderhq } from "@founderhq/events";

export function FounderHqAnalytics() {
  useEffect(() => {
    founderhq.init("fhq_pk_XXXX");
  }, []);
  return null;
}
```

## 3. Identify the person when they sign in

```ts
founderhq.identify("user_8421", {
  email: "jane@acme.com",
  plan: "pro",
});
```

Pass your own stable user ID, not an email. FounderHQ merges the
visitor's anonymous history into that contact.

Call `founderhq.reset()` when the person signs out, so the next visitor
on that browser starts clean.

## 4. Capture your first event

```ts
founderhq.capture("trial.started", { plan: "pro" });
```

Use lowercase names you will still understand in six months. Event
names that start with `$` are reserved.

## Verify

1. Run your app and trigger the event.
2. In FounderHQ, open **Sequences → Events**.
3. You see `trial.started` with `plan: pro`, plus a `$pageview`.
4. Open **Sequences → Contacts**. Jane is there with her email.

Events can take a few seconds to appear. The SDK batches them. To send
immediately, `await founderhq.flush()`.

## Troubleshoot

### Nothing appears in Events

Check the network tab. If requests to `/i/v2/e` fail with a 401 or 403,
the key is wrong or your origin is not allowed. Check **Allowed
origins** on the key in **Sequences → Settings → Event API keys**.

### Events fire twice in development

React Strict Mode runs effects twice. `init` is safe to call twice, but
a `capture` inside an effect is not. Capture on the user's action, not
on render.

## Next

- [Identity and contacts](/analytics/concepts/identity-and-contacts)
- [Send server-side events](/analytics/getting-started/quickstart-server-node)
- [Web SDK options](/analytics/sdks/web)
