React
Initialize Ucoder Insight once in a React application.
React
Initialize the SDK from a component that mounts once near the root of your application.
Using Next.js? Use the Next.js guide instead — it handles App Router and Pages Router differently from a plain React SPA.
import { useEffect } from "react";
import { initUcoderInsight } from "ucoder-insight";
export default function Analytics() {
useEffect(() => {
void initUcoderInsight("YOUR_PUBLIC_TRACKING_ID");
}, []);
return null;
}Where to render it
Render <Analytics /> once, near the root of your component tree — for example in App.tsx:
function App() {
return (
<>
<Analytics />
<YourAppRoutes />
</>
);
}Do not initialize the SDK separately in every route component.
In development, React's StrictMode intentionally mounts effects twice. You
may see initUcoderInsight run twice in the console — this is expected and
does not cause duplicate tracking in production.
Tracking route changes in a single-page app
React Router (and most other client-side routers) navigate by calling the browser's history.pushState / history.replaceState APIs, or by triggering popstate (back/forward button), instead of a full page reload. A normal analytics script that only listens for the load event would miss every one of these navigations.
Ucoder Insight handles this automatically once initialized:
- It patches
history.pushStateandhistory.replaceStateso that every programmatic navigation (e.g.navigate("/pricing"),<Link to="/about" />) is detected the moment it happens. - It listens for the native
popstateevent to catch browser back/forward navigation. - On each detected change, it records a new page view for the updated URL — automatically, with no extra code in your routes or components.
Because tracking is based on pushState/replaceState/popstate, this works
with any router built on the History API (React Router, TanStack Router,
Wouter, etc.) without router-specific integration code.
You do not need to call any trackPageView()-style function manually — as long as <Analytics /> is mounted once at the root, every route change is picked up automatically for the lifetime of the page.
If your app uses hash-based routing (URLs like /#/pricing) instead of
the History API, route changes may not trigger pushState/popstate the same
way. Verify tracking works correctly if you're on a hash router.
See Configuration for supported options.