React
Install HumanBehavior in a client-rendered React app: package, Vite env vars, provider placement, direct tracker init, and wizard detection.
Generic React means a browser-rendered React app such as Vite or Create React App, not Next.js, Remix, Gatsby, or another React meta-framework. In this shape it is safe to wrap the client app with the shipped React provider.
What the shipped wizard detects
The wizard's React config is a fallback. It matches a project when:
| Signal | Meaning |
|---|---|
package.json has react | The app is React-based |
No next dependency | Not Next.js |
No gatsby dependency | Not Gatsby |
No @remix-run/react dependency | Not classic Remix |
No @react-router/dev dependency | Not React Router 7 / Remix successor |
If one of those meta-framework packages exists, use that framework guide instead of this one.
Package
pnpm add humanbehavior-jsUse the package manager your app already uses. The wizard detects package managers and installs through the package manager instead of hand-editing package.json.
Environment variables
For Vite-style React, only VITE_ variables are exposed to browser code:
VITE_HUMANBEHAVIOR_API_KEY=your-api-key
VITE_HUMANBEHAVIOR_INGESTION_URL=https://ingest.humanbehavior.coVITE_HUMANBEHAVIOR_INGESTION_URL is optional for production because the SDK defaults to hosted ingestion. Set it for local stacks, reverse proxies, or custom ingestion hosts.
Restart the dev server after adding env vars. A hot reload usually does not reload Vite's env snapshot.
Recommended provider init
Use this in a client-rendered React app entry such as src/main.tsx:
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { HumanBehaviorProvider } from "humanbehavior-js/react";
import App from "./App";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<HumanBehaviorProvider
apiKey={import.meta.env.VITE_HUMANBEHAVIOR_API_KEY}
options={{
ingestionUrl: import.meta.env.VITE_HUMANBEHAVIOR_INGESTION_URL,
redactionStrategy: { mode: "visibility-first" },
}}
>
<App />
</HumanBehaviorProvider>
</StrictMode>,
);Direct tracker init alternative
If you do not need React context, initialize the tracker directly:
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { HumanBehaviorTracker } from "humanbehavior-js";
import App from "./App";
const apiKey = import.meta.env.VITE_HUMANBEHAVIOR_API_KEY;
if (apiKey) {
HumanBehaviorTracker.init(apiKey, {
ingestionUrl: import.meta.env.VITE_HUMANBEHAVIOR_INGESTION_URL,
});
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
);Both patterns use the same runtime SDK. The provider adds React context helpers; direct init is smaller and explicit.
Provider API that ships
| Prop | Required | Meaning |
|---|---|---|
apiKey | Required unless client is provided | Project API key |
client | Optional | Existing HumanBehaviorTracker instance |
children | Required | Your React tree |
options.ingestionUrl | Optional | Override default ingestion host |
options.redactionStrategy | Optional | privacy-first or visibility-first replay redaction |
options.enableAutomaticTracking | Optional | Opt out with false |
options.enableConsoleTracking | Optional | Console warn/error capture, default on |
options.enableNetworkTracking | Optional | Network error capture, default on |
options.enableErrorTracking | Optional | Runtime error capture, default on |
options.enableWebVitals | Optional | Core Web Vitals capture, default on |
options.enableTracing | Optional | Page-load/resource/custom span tracing, default on |
options.release / environment / commitSha / dist | Optional | Error and release attribution |
Do not pass endpoint. Use options.ingestionUrl.
Files to edit
| Project shape | Typical file |
|---|---|
| Vite React | src/main.tsx |
| CRA-style React | src/index.tsx |
| Custom browser app shell | The one file that calls createRoot or hydrateRoot |
Put init as close to the client root as possible. Do not initialize in server-only build scripts, tests, or Storybook-only files unless you intentionally want those sessions.
Common pitfalls
| Pitfall | Symptom | Fix |
|---|---|---|
Missing VITE_ prefix | apiKey is undefined in the browser | Rename env var and restart dev server |
| Wrapping a meta-framework root | Hydration warnings or duplicate init | Use the framework-specific guide |
Calling init in multiple entries | One global tracker wins, confusing setup | Initialize once per browser app |
| Hardcoding keys | Secret leaks into git | Use env vars, even though browser keys are public credentials |
| Using dashboard origin as ingestion | Network 404s to /api/ingestion/* | Use hosted ingestion, local ingestion, or a configured proxy |
What automatic tracking starts
The SDK starts replay recording and automatic browser capture after init. By default, the tracker enables:
- replay session capture
- page view/navigation events
- automatic click/form/link tracking
- console warn/error capture
- network error capture
- runtime error capture
- web vitals and tracing
Tune those through Init reference when needed.
Verify
- Open the app in a normal browser tab.
- Check DevTools for
/api/ingestion/eventsand/heartbeat(init is not required). - Click around for 30 seconds.
- Open Replays and look for the newest session.
- If nothing appears, use Verify data is flowing.
When not to use this page
Use another guide if your project has:
| Dependency / file | Use |
|---|---|
next or next.config.* | Next.js |
@remix-run/react or @react-router/dev | Remix |
gatsby or gatsby-config.* | Gatsby |
| Server-rendered React shell | Its framework-specific browser entry |