React & Next.js SDK
Full reference for @onramp-sdk/react. Works with React 18+, Next.js App Router, and Next.js Pages Router.
Installation
npm install @onramp-sdk/react
Setup
Next.js App Router
Add OnRampProvider to your root layout. It initializes once on the client and is SSR-safe - it no-ops on the server.
// app/layout.tsx
import { OnRampProvider } from '@onramp-sdk/react'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<OnRampProvider apiKey="onr_xxxxxxxxxxxx" appVersion="2.4.1">
{children}
</OnRampProvider>
</body>
</html>
)
}
React (Vite, CRA, etc.)
// main.tsx
import { createRoot } from 'react-dom/client'
import { OnRampProvider } from '@onramp-sdk/react'
import App from './App'
createRoot(document.getElementById('root')!).render(
<OnRampProvider apiKey="onr_xxxxxxxxxxxx" appVersion="2.4.1">
<App />
</OnRampProvider>
)
Your API key is on the Settings page of each app in the dashboard.
OnRampProvider props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | string | Yes | - | Your API key from Settings |
appVersion | string | No | - | Version string, e.g. "2.4.1" - shows in the version breakdown |
framework | string | No | 'react' | Label shown in the dashboard - set 'nextjs' to distinguish surfaces |
sessionTimeoutMs | number | No | 1_800_000 | Idle time (ms) before a new session starts (default 30 min) |
anonymousIdMaxAgeMs | number | No | 31_536_000_000 | How long before the anonymous ID rotates (default 365 days) |
host | string | No | - | Override ingestion endpoint (for self-hosting) |
Tracking steps
useTrackStep(name, options?)
Fires a funnel milestone the moment the component mounts. Re-fires if name changes.
'use client'
import { useTrackStep } from '@onramp-sdk/react'
function ProfileSetup() {
useTrackStep('profile_setup_viewed')
return <form>...</form>
}
Options
| Option | Type | Description |
|---|---|---|
properties | Record<string, string | number | boolean> | Custom key-value data attached to the event |
enabled | boolean | Skip tracking while false - useful for gating on a loaded/ready state (default true) |
// Only track once data has loaded
useTrackStep('checkout_viewed', {
enabled: !!user,
properties: { plan: user?.plan },
})
useOnRamp()
Returns the tracker API from any client component below <OnRampProvider>.
'use client'
import { useOnRamp } from '@onramp-sdk/react'
function UpgradeButton() {
const { step, getIds } = useOnRamp()
async function handleClick() {
step('upgrade_clicked', { properties: { plan: 'pro' } })
// Pass IDs to your server to fire backend events tied to this session
const { anonymousId, sessionId } = getIds()
await fetch('/api/checkout', {
method: 'POST',
body: JSON.stringify({ anonymousId, sessionId, plan: 'pro' }),
})
}
return <button onClick={handleClick}>Upgrade</button>
}
API
| Method | Description |
|---|---|
step(name, options?) | Record a funnel milestone |
identify(traits) | Associate the current user with known traits for integration matching (optional) |
flush() | Flush queued events immediately (also runs on tab close) |
newSession() | Force-start a new session - call after logout |
getIds() | Returns { anonymousId, sessionId } for server-side event correlation |
identify(traits)
Associates the current anonymous user with known identity traits. Call once after sign-in so integrations (Stripe, RevenueCat) can match the user to external records.
'use client'
import { useOnRamp } from '@onramp-sdk/react'
function AuthCallback({ user }: { user: User }) {
const { identify } = useOnRamp()
useEffect(() => {
identify({ email: user.email, userId: user.id })
}, [user.id])
}
identify() is entirely optional. Omit it if you have no integrations connected, or if users in your app prefer not to share identity traits. All funnel and retention features work without it.
Route tracking (Next.js App Router)
OnRampRouteTracker auto-records every App Router navigation as a nav_entered event. These appear in session timelines and the journey map but are kept out of your defined funnels automatically.
Mount it once inside OnRampProvider in your root layout:
// app/layout.tsx
import { OnRampProvider } from '@onramp-sdk/react'
import { OnRampRouteTracker } from '@onramp-sdk/react/next'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<OnRampProvider apiKey="onr_xxxxxxxxxxxx" framework="nextjs">
<OnRampRouteTracker />
{children}
</OnRampProvider>
</body>
</html>
)
}
OnRampRouteTracker is exported from @onramp-sdk/react/next (a separate entry point) so that non-Next.js React apps don't pull in the next package.
Session management
Call newSession() after logout so the next user gets a clean session:
'use client'
import { useOnRamp } from '@onramp-sdk/react'
function LogoutButton() {
const { newSession } = useOnRamp()
async function handleLogout() {
await signOut()
newSession()
}
return <button onClick={handleLogout}>Sign out</button>
}
Storage
Anonymous IDs and session state are stored in localStorage under @onramp/anonymous_id and @onramp/session. No HTTP cookies are set.
No HTTP cookies, but consent may still apply
OnRamp uses localStorage, not HTTP cookies, so browser-level cookie blocking won't affect it. However, the EU ePrivacy Directive covers all client-side storage for analytics - EU/UK developers should include OnRamp in their consent flow and initialise the SDK only after consent is granted. See the Privacy & data page for the full breakdown.
TypeScript
The SDK ships full TypeScript types. No @types/ package needed.
import type { OnRampApi } from '@onramp-sdk/react'
function MyComponent() {
const onramp: OnRampApi = useOnRamp()
// ...
}
