---
title: "Add Togo to a React app (Vite)"
description: "Install the browser SDK in a React single-page app built with Vite, and record page views and events."
canonical: "https://www.togohq.ai/docs/react"
applies_to: "@togohq/sdk-browser 1.x"
updated: "2026-11-03T00:00:00Z"
---

# Add Togo to a React app (Vite)

Install the browser SDK in a React single-page app built with Vite, and record page views and events.

This page installs Togo by hand. To have your coding agent do it instead, see
[Install Togo with your AI agent](/docs/install). Using Next.js? See [Next.js](/docs/nextjs).

## Install the SDK

```bash
npm install @togohq/sdk-browser
```

Put the write key in an environment variable: the **test** key (`togo_pkt_…`) in `.env.local`,
the **live** key (`togo_pkl_…`) in your production build. Write keys are public, so the `VITE_`
prefix, which ships the value in the bundle, is correct.

```bash
# .env.local
VITE_TOGO_WRITE_KEY=togo_pkt_your_test_key
```

## Create one client, at start-up

```ts
// src/analytics.ts
import { init } from '@togohq/sdk-browser';

export const analytics = init({ writeKey: import.meta.env.VITE_TOGO_WRITE_KEY });
```

Import it from your entry point (`src/main.tsx`) so it runs before anything else. The first event
carries the referrer and the campaign parameters, which are gone once the visitor navigates.
`init()` returns at once and never throws.

## Record page views

With React Router, send a page view whenever the location changes:

```tsx
// src/page-views.tsx
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { analytics } from './analytics';

export function PageViews() {
  const { pathname } = useLocation();
  useEffect(() => {
    analytics.track('page_viewed');
  }, [pathname]);
  return null;
}
```

Render `<PageViews />` once inside your router. Every event already carries the URL, path,
referrer and campaign, so `page_viewed` needs no properties.

## Track, identify and reset

```ts
analytics.track('project_created', { template: 'blank' });
analytics.identify(user.id); // after sign-in
analytics.reset(); // on sign-out
```

Use event names you already have, or lowercase `snake_case` for new ones. Never put an email
address or user-typed text in a property ([What never goes in an
event](/docs/concepts/personal-data)).

## Check it works

Run `npm run dev`, click around, and confirm the events arrived:
[Check that events arrive](/docs/verify).
