# Quickstart: React > Install the OakData SDK in a React (Vite / CRA) single-page app and identify users. Source: https://oakdata.co/docs/quickstart/react --- In a React single-page app (Vite, Create React App, …) you call `oak.init()` once in your entry file, before `ReactDOM.createRoot`. The SDK tracks client-side route changes on its own, so React Router needs no extra wiring. In a hurry? Paste this prompt into Claude Code, Cursor, or any agent working in your repo, and give it your public key when asked: **Prompt for a coding agent:** ``` Set up OakData product analytics in this React single-page app using the oakdata-js SDK. 1. Install the package: run "npm install oakdata-js". 2. Create or edit .env at the project root and add: VITE_OAK_KEY= VITE_OAK_HOST=https://oakdata.co Ask me for the key value if you don't already have it. If this is Create React App, use REACT_APP_ prefixes and read them from process.env instead. 3. In the entry file (e.g. src/main.tsx), before ReactDOM.createRoot, import oakdata-js and call oak.init(import.meta.env.VITE_OAK_KEY, { api_host: import.meta.env.VITE_OAK_HOST }). 4. Wherever auth resolves with a signed-in user, call oak.identify(user.id, { email: user.email }). On sign-out, call oak.reset(). Use my existing auth code. Don't add any other analytics providers or wrapper components. Show me the changes before applying them. ``` Prefer to wire it up yourself? The steps below are exactly what that prompt does. ## 1. Install the package **npm** ```bash npm install oakdata-js ``` **pnpm** ```bash pnpm add oakdata-js ``` **yarn** ```bash yarn add oakdata-js ``` **bun** ```bash bun add oakdata-js ``` ## 2. Add your keys With Vite, env vars exposed to the browser need the `VITE_` prefix. Use your **public** key (`oak_pub_…`) - it's safe to ship in client code. **.env** ```bash VITE_OAK_KEY=oak_pub_xxxxxxxxxxxxxxxxxxxxxxxx VITE_OAK_HOST=https://oakdata.co ``` > **Create React App** On CRA, use the `REACT_APP_` prefix instead (`REACT_APP_OAK_KEY`) and read it from `process.env`. ## 3. Initialize before render **src/main.tsx** ```tsx import React from 'react' import ReactDOM from 'react-dom/client' import oak from 'oakdata-js' import App from './App' oak.init(import.meta.env.VITE_OAK_KEY, { api_host: import.meta.env.VITE_OAK_HOST, }) ReactDOM.createRoot(document.getElementById('root')!).render( , ) ``` Pageviews and [autocapture](https://oakdata.co/docs/sdk/autocapture) start immediately. The SDK hooks the History and Navigation APIs, so every navigation fires a pageview - no router plugin needed. ## 4. Identify signed-in users When auth resolves, call `identify`; on sign-out, call `reset` so the next person on that browser starts fresh. A small effect in your auth provider covers both: **AuthProvider.tsx** ```tsx import { useEffect } from 'react' import oak from 'oakdata-js' function useOakIdentity(user) { useEffect(() => { if (user) { oak.identify(user.id, { email: user.email, name: user.name }) } else { oak.reset() // signed out - start a fresh anonymous identity } }, [user]) } ``` `identify` links everything the visitor did anonymously to the identified profile - see [identity resolution](https://oakdata.co/docs/concepts/identity). Calls made before `init()` are queued and replayed, so ordering never matters. ## 5. Track custom events **Pricing.tsx** ```tsx import oak from 'oakdata-js' function UpgradeButton() { return ( ) } ``` The [SDK reference](https://oakdata.co/docs/sdk/reference) covers every method and init option.