React
For a single-page app built with Vite or Create React App. Wrap the tree once in NohmoProvider; because React Router has no single layout hook, page views are tracked from the History API — so there is nothing to add per route.
Install
npm install nohmo
Wrap your app
Open your root App.tsx and wrap with NohmoProvider.
// src/App.tsximport { NohmoProvider } from 'nohmo'export default function App() {return (<NohmoProviderprojectId="proj_xxxx"apiKey="pk_xxxx"><YourApp /></NohmoProvider>)}
Note: Use environment variables in production: import.meta.env.VITE_NOHMO_PROJECT_ID for Vite or process.env.REACT_APP_NOHMO_PROJECT_ID for CRA.
Page views — nothing to do
Route changes are tracked for you. The provider watches the History API, which every client-side router goes through, so React Router, Wouter, TanStack Router and hand-rolled routing all work with no per-page code — including back/forward and redirects.
import { useNohmo } from 'nohmo'export default function PricingPage() {// No usePageView call — navigating here already sent PAGE_VIEW.const { send } = useNohmo()return <button onClick={() => send('cta_clicked')}>Get started</button>}
Note: Only needed for a screen that changes without touching the URL — a wizard step, a tab, a modal you treat as a page. Then call usePageView('/checkout/shipping') to name it yourself.
Identify users at login (optional)
const { linkUser } = useNohmo()const handleLogin = async () => {const user = await loginAPI()await linkUser(user.id, user.email)}
You're all set
Open your Nohmo dashboard. You should see devices and events appearing within seconds of your first page load.
Note: Using Next.js? Use the Next.js guide instead — its provider is preconfigured for it. Route tracking itself is identical — both read the History API.
Next steps
Auto-capture lists what arrives without any code of your own. Custom events covers sending your own, and Configuration has every option the SDK accepts.