---
title: "Quickstart"
description: "Send your first event to Pug in under five minutes — install the Web SDK, track a page view, and confirm it in the dashboard."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.pug.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

Send your first event to Pug in under five minutes. By the end you'll have the Web SDK installed, a `page_view` flowing into your project, and confirmation in the dashboard.

## Prerequisites

- A Pug account — [sign up at app.pug.sh](https://app.pug.sh) (or your self-hosted dashboard)
- Node.js 18+ and a bundler-based web project (Vite, Next.js, etc.)

Building a **mobile app**? This quickstart is web-only — start with the [Flutter setup](/sdks?platform=flutter) instead.

Building a **backend**? Use the server-side [Node SDK](/sdks?platform=node), or POST events directly from any language — see [Integrate over HTTP](/sdks?platform=http).

## 1. Create a project and grab your keys

1. Sign in to the [dashboard](https://app.pug.sh).
2. Create an **organization**, then a **project** inside it.
3. Collect the two values this quickstart needs:
- **Project ID** — in the dashboard URL: `/p/<projectId>`.
- **Public key** (`pub_…`) — under the **API Keys** section of your project **Overview**; safe to ship in client code.

The Web SDK authenticates with your **public key**. (The same screen also shows a server-side **private key** — you don't need it here; see [Authentication](/get-started/authentication).)

## 2. Install the Web SDK

```bash
npm install @pug-sh/browser
```

See [Installation](/sdks#install) for pnpm, yarn, bun, and framework-specific setup. No bundler? Drop in the [CDN loader snippet](/sdks#script-tag-loader) instead.

## 3. Initialize and track

Call `init` once at startup, then `track` anywhere. `init` registers your project ID and public key, starts the session, and begins auto-tracking (page views, clicks). The first argument to `track` is the **event name** — any string you choose.

### Vite / React

```ts
// src/main.tsx
import { init, track } from '@pug-sh/browser'

init('YOUR_PROJECT_ID', {
  apiKey: 'pub_YOUR_PUBLIC_KEY'
})

track('signup', { plan: 'pro' })
```

### Next.js App Router

`init` must run in the browser, so wrap it in a client component:

```tsx
// components/PugProvider.tsx
'use client'

import { init } from '@pug-sh/browser'
import { useEffect } from 'react'

export function PugProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
init(process.env.NEXT_PUBLIC_PUG_PROJECT_ID!, {
  apiKey: process.env.NEXT_PUBLIC_PUG_PUBLIC_KEY!
})
  }, [])

  return <>{children}</>
}
```

Add `PugProvider` to your root layout and store the values in `.env.local`:

```
NEXT_PUBLIC_PUG_PROJECT_ID=your-project-id
NEXT_PUBLIC_PUG_PUBLIC_KEY=pub_your_public_key
```

> Only ever expose the **public** key with `NEXT_PUBLIC_*`. The private key stays server-side.

## 4. Verify in the dashboard

1. Open your project in the dashboard.
2. Go to **Live** — the active visitor count should tick up within a few seconds.
3. Go to **Events** — `page_view` (auto-tracked on init) and your `signup` event should appear.

Events are batched client-side and flushed every few seconds, so allow up to ~10 seconds for the first one. Force an immediate send with `track('signup', {}, { immediate: true })`.

## 5. Identify a user (optional)

After sign-in, link anonymous activity to a known user. `identify()` returns a promise and **never throws** — failures are logged — so you can `await` it without a try/catch:

```ts
import { identify } from '@pug-sh/browser'

await identify('user-123', { email: 'user@example.com', plan: 'pro' })
```

On sign-out, call `reset()` to start a fresh anonymous session. See [Identity & sessions](/sdks#identify-and-sessions).

## You're done when…

- [ ] `page_view` and `signup` appear in **Live** and **Events**
- [ ] Auto-tracked clicks/scrolls appear (defaults are on)
- [ ] `identify()` merges pre-login events into a profile (optional)

## Common issues

| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| No events in dashboard | Wrong project ID or public key | Re-check the **API Keys** section of your project **Overview** |
| Events in console but not dashboard | `dryRun: true` in init options | Remove `dryRun` or set `false` |
| CORS errors in the browser | Wrong `endpoint` | Use `https://api.pugs.dev` or your self-hosted URL |
| Nothing happens, no errors | `init()` ran outside the browser (SSR) | Call `init()` in a client component / `useEffect` |
| Events delayed | Client-side batching | Normal (see step 4) — or use `{ immediate: true }` |

## Next steps

**Next: [Core concepts](/get-started/concepts)** — orgs, projects, keys, and the event pipeline. Then:

- [Initialization](/sdks#initialize) — batching, sessions, auto-track options
- [Tracking events](/sdks#track-events) — custom events and well-known schemas
- [Authentication](/get-started/authentication) — public vs private keys

Source: https://docs.pug.sh/get-started/index.mdx
