I have the following SPA that uses react router:
ReactDOM.createRoot(document.getElementById("root")!).render(
<StrictMode>
<Providers>
<BrowserRouter>
<Routes>
<Route element={<ProtectedRoutes />}>
<Route path="/dashboard" element={<MainPage />} />
<Route path="/dashboard/setup" element={<SetupPage />} />
<Route path="/dashboard/project/:projectId" element={<ProjectPage />} />
</Route>
<Route path="/admin" element={<ProtectedRoutes admin />}>
<Route path="" element={<div>you are admin</div>} />
<Route path="users" element={<UsersPage />} />
<Route path="data/view" element={<DataViewPage />} />
<Route path="tasks" element={<TasksPage />} />
</Route>
<Route element={<PublicOnlyRoutes redirectTo="/dashboard?redirect=true" />}>
<Route path="/login" element={<LoginPage />} />
</Route>
<Route path="/" element={<HomePage />} />
<Route
path="/demo"
element={<DemoComponent message="Sample message" name="User" />}
/>
</Routes>
</BrowserRouter>
</Providers>
</StrictMode>,
);
I would like to use Posthog's event capturing with this to track when users navigate around the application. Like this:
function PostHogIdentifier() {
const location = useLocation();
// Track pageviews
useEffect(() => {
if (posthog) {
console.log("Capturing pageview", window.location.href);
posthog.capture(
'$pageview',
{
'$current_url': window.location.href,
}
)
}
}, [location])
return null;
}
But, I can't do this because the useLocation
hook must be run inside of the BrowserRouter
. And I'm not sure how to do this since the BrowserRouter
only supports Route
and Routes
child components.
But, I can't do this because the
useLocation
hook must be run inside of theBrowserRouter
.
This is true, the useLocation
hook can only be called in a component rendered within routing context.
And I'm not sure how to do this since the
BrowserRouter
only supportsRoute
andRoutes
child components.
This is incorrect, the BrowserRouter
can render anything as children, it is the Route
and React.Fragment
components that are the only valid children of the Routes
component.
PostHogIdentifier
only needs to be rendered within the ReactTree created by BrowserRouter
, i.e. it only needs to be rendered as a descendent.
Example:
ReactDOM.createRoot(document.getElementById("root")!).render(
<StrictMode>
<Providers>
<BrowserRouter>
<PostHogIdentifier /> {/* <-- rendered within routing context */}
<Routes>
<Route element={<ProtectedRoutes />}>
<Route path="/dashboard" element={<MainPage />} />
<Route path="/dashboard/setup" element={<SetupPage />} />
<Route
path="/dashboard/project/:projectId"
element={<ProjectPage />}
/>
</Route>
<Route path="/admin" element={<ProtectedRoutes admin />}>
<Route path="" element={<div>you are admin</div>} />
<Route path="users" element={<UsersPage />} />
<Route path="data/view" element={<DataViewPage />} />
<Route path="tasks" element={<TasksPage />} />
</Route>
<Route
element={
<PublicOnlyRoutes redirectTo="/dashboard?redirect=true" />
}
>
<Route path="/login" element={<LoginPage />} />
</Route>
<Route path="/" element={<HomePage />} />
<Route
path="/demo"
element={<DemoComponent message="Sample message" name="User" />}
/>
</Routes>
</BrowserRouter>
</Providers>
</StrictMode>,
);