Skip to content

React and Next.js

Facts reviewed:

Follow the quickstart prerequisites first. useAnalytics is an OwlEye controller factory, not a React hook. Call it from an effect so server rendering does not create a tracker. Mount one instance near the application root.

"use client";
import { useEffect } from "react";
import { useAnalytics } from "@owleye/analytics";
import { trackRules } from "@owleye/analytics/rules";
export function OwlEyeTracking({ allowed }: { allowed: boolean }) {
useEffect(() => {
if (!allowed) return;
const analytics = useAnalytics("your-site-id");
const rules = trackRules("your-site-id");
return () => {
rules.stop();
analytics.stop();
};
}, [allowed]);
return null;
}

Pass allowed from the site’s consent or lawful-basis flow. In a Next.js App Router application, render this client component inside the root layout. Keep the layout server-rendered; only the tracking component needs the client directive. A plain React application can use the same component without the directive.

The controller observes History API navigation. Do not add a second route effect that sends a manual page view for every URL change, or you will count the same navigation twice. Query and fragment changes alone do not produce page views unless trackQueryChanges or trackHashChanges is enabled. These counting options are separate from captureQuery and captureHash, which control the URL content sent.

React development Strict Mode can initialize, clean up, and initialize an effect again. The current SDK shares active instances and avoids another automatic page view on a same-URL remount. Cleanup removes listeners, but cannot retract requests already started. Use a separate development site or mock: true while developing, and verify counts in a production build.

Changing allowed to false stops both controllers. A later true value creates a fresh rules controller and fetches current rules. Do not put credentials, user IDs, or email addresses into global event properties.