Chapter 160 · Omnibus Instrument Integration
Subchapter 160.51
references/react-router-v6.mdMarkdown12 KBView on GitHub
This guide walks you through setting up PostHog for React Router V6. If you’re using React Router v7, find the guide for that mode in the React Router page. If you’re using React with another framework, go to the .
1
Required
First, you’ll need to install posthog-js (opens in a new tab) and @posthog/react using your package manager. These packages allow you to capture client-side events.
PostHog AI
npm install --save posthog-js @posthog/reactyarn add posthog-js @posthog/reactpnpm add posthog-js @posthog/reactbun add posthog-js @posthog/react2
Required
Add your environment variables to your .env.local file and to your hosting provider (e.g. Vercel, Netlify, AWS). You can find your project token and host in your project settings (opens in a new tab). If you’re using Vite, including VITE_PUBLIC_ in their names ensures they are accessible in the frontend.
.env.local
PostHog AI
VITE_PUBLIC_POSTHOG_TOKEN=<ph_project_token>
VITE_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com3
Required
In declarative mode, you’ll need to wrap your BrowserRouter with the PostHogProvider context. This passes an initialized PostHog client to your app.
src/main.tsx
PostHog AI
import { StrictMode } from "react";
import ReactDOM from "react-dom/client";
import
Checkpoint
Confirm that you can capture client-side events and see them in your PostHog project
At this point, you should be able to capture client-side events and see them in your PostHog project. This includes basic events like page views and button clicks that are autocaptured (opens in a new tab).
You can also try to capture a custom event to verify it’s working. You can access PostHog in any component using the usePostHog hook.
TSX
PostHog AI
import { usePostHog } from '@posthog/react'
function App() {
4
Required
On the client-side, you can access the PostHog client using the usePostHog hook. This hook returns the initialized PostHog client, which you can use to call PostHog methods. For example:
TSX
PostHog AI
import { usePostHog } from '@posthog/react'
function App() {
const posthog = usePostHog()
return <button onClick={() =>
5
Recommended
Now that you can capture basic client-side events, you’ll want to identify your user so you can associate users with captured events.
Generally, you identify users when they log in or when they input some identifiable information (e.g. email, name, etc.). You can identify users by calling the identify method on the PostHog client:
TSX
PostHog AI
export default function Login() {
const { user, login } = useAuth
6
Recommended
PostHog can capture exceptions thrown in your app through an error boundary. PostHog provides a PostHogErrorBoundary component that you can use to capture exceptions. You can wrap your app with this component to capture exceptions.
TSX
PostHog AI
ReactDOM.createRoot(root).render(
<StrictMode>
<PostHogProvider client={posthog}>
<
7
Recommended
The PostHogCaptureOnViewed component enables you to automatically capture events when elements scroll into view in the browser. This is useful for tracking impressions of important content, monitoring user engagement with specific sections, or understanding which parts of your page users are actually seeing.
The component wraps your content and sends a $element_viewed event to PostHog when the wrapped element becomes visible in the viewport. It only fires once per component instance.
Basic usage:
React
PostHog AI
import { PostHogCaptureOnViewed } from '@posthog/react'
function App() {
return (
<PostHogCaptureOnViewed name
8
Recommended
Now that you’ve set up PostHog for React Router V7 in declarative mode, you can continue to set up server-side analytics. You can find our other SDKs in the SDKs page (opens in a new tab).
To help PostHog track your user sessions across the client and server, you’ll need to add the __add_tracing_headers: ['your-backend-domain1.com', 'your-backend-domain2.com', ...] option to your PostHog initialization:
TSX
PostHog AI
posthog.init(import.meta.env.VITE_PUBLIC_POSTHOG_TOKEN, {
9
Recommended
Now that you’ve set up PostHog for React Router, you can start capturing events and exceptions in your app.
To get the most out of PostHog, you should familiarize yourself with the following:
Ask a question
HelpfulCould be better
This initializes PostHog and passes it to your app through the PostHogProvider context.
TypeError: Cannot read properties of undefined
If you see the error TypeError: Cannot read properties of undefined (reading '...') this is likely because you tried to call a posthog function when posthog was not initialized (such as during the initial render). On purpose, we still render the children even if PostHog is not initialized so that your app still loads even if PostHog can’t load.
To fix this error, add a check that posthog has been initialized such as:
React
PostHog AI
useEffect(() => {
posthog?.capture('test') // using optional chaining (recommended)
if (posthog) {
posthog.capture('test') // using an if statement
}
}, [posthog])Typescript helps protect against these errors.
You should see these events in a minute or two in the activity tab (opens in a new tab).
For a complete list of available methods, see the posthog-js documentation (opens in a new tab).
PostHog automatically generates anonymous IDs for users before they’re identified. When you call identify, a new identified person is created. All previous events tracked with the anonymous ID link to the new identified distinct ID, and all future captures on the same browser associate with the identified person.
This automatically captures exceptions thrown in your React Router app using the posthog.captureException() method.
With custom properties:
You can include additional properties with the event to provide more context:
React
PostHog AI
<PostHogCaptureOnViewed
name="product-card"
properties={{
product_id: '123',
category: 'electronics',
price: 299.99
}}
>
<ProductCard />
</PostHogCaptureOnViewed>Tracking multiple children:
Use trackAllChildren to track each child element separately. This is useful for galleries or lists where you want to know which specific items were viewed:
React
PostHog AI
<PostHogCaptureOnViewed
name="product-gallery"
properties={{ gallery_type: 'featured' }}
trackAllChildren
>
<ProductCard id="1" />
<ProductCard id="2" />
<ProductCard id="3" />
</PostHogCaptureOnViewed>When trackAllChildren is enabled, each child element sends its own event with a child_index property indicating its position.
Custom intersection observer options:
You can customize when elements are considered “viewed” by passing options to the IntersectionObserver:
React
PostHog AI
<PostHogCaptureOnViewed
name="footer"
observerOptions={{
threshold: 0.5, // Element is 50% visible
rootMargin: '0px'
}}
>
<Footer />
</PostHogCaptureOnViewed>The component passes all other props to the wrapper div, so you can add styling, classes, or other HTML attributes as needed.
This adds the X-POSTHOG-DISTINCT-ID and X-POSTHOG-SESSION-ID headers to your requests, which you can later use on the server-side.