Skip to Content
DocsQuickstart

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  (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 instead.

Building a backend? Use the server-side Node SDK, or POST events directly from any language — see Integrate over HTTP.

1. Create a project and grab your keys

  1. Sign in to the dashboard .
  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.)

2. Install the Web SDK

npm install @pug-sh/browser

See Installation for pnpm, yarn, bun, and framework-specific setup. No bundler? Drop in the CDN loader snippet 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

// 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:

// 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 Eventspage_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:

import { identify } from '@pug-sh/browser' await identify('user-123', { email: '[email protected]', plan: 'pro' })

On sign-out, call reset() to start a fresh anonymous session. See Identity & 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

SymptomLikely causeFix
No events in dashboardWrong project ID or public keyRe-check the API Keys section of your project Overview
Events in console but not dashboarddryRun: true in init optionsRemove dryRun or set false
CORS errors in the browserWrong endpointUse https://api.pugs.dev or your self-hosted URL
Nothing happens, no errorsinit() ran outside the browser (SSR)Call init() in a client component / useEffect
Events delayedClient-side batchingNormal (see step 4) — or use { immediate: true }

Next steps

Next: Core concepts — orgs, projects, keys, and the event pipeline. Then:

Last updated on