Quickstart: React

Install the OakData SDK in a React (Vite / CRA) single-page app and identify users.

In a plain React single-page app (Vite, Create React App, etc.) you initialize OakData once, as early as possible — typically in your entry file before ReactDOM.createRoot. The SDK tracks client-side route changes on its own, so a single init covers your whole app.

1. Install the package

Terminal
bash
npm install oakdata-js

2. Add your keys

With Vite, environment variables exposed to the browser must be prefixed with VITE_. Put your public key (oak_pub_…) here — 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(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

Pageviews and autocapture start immediately. The SDK hooks the History API and the experimental Navigation API, so router libraries like React Router fire a pageview on every navigation without extra wiring.

4. Identify users

After authentication resolves, identify the user. A small effect in your auth provider is a good home for it:

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])
}

5. Track custom events

Pricing.tsx
tsx
import oak from 'oakdata-js'

function UpgradeButton() {
  return (
    <button onClick={() => oak.capture('upgrade_clicked', { plan: 'pro' })}>
      Upgrade
    </button>
  )
}

See the SDK reference for the complete API.