Skip to main content

React and Next.js

Goal: load OptSens first-party in a React or Next.js app, tell it about client-side route changes, and react to consent in your components.

In a single-page app the page does not reload between routes. OptSens needs to be told when the route changes. See SPA support for the underlying methods.

Next.js: load the snippet in the head

Load the script with beforeInteractive to run it before your other tags, the same as a first-party head snippet. In the App Router, put it in the root app/layout.tsx.

// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<Script
src="https://cdn.optsens.com/optsens.min.js/YOUR_DOMAIN_ID"
strategy="beforeInteractive"
/>
</head>
<body>{children}</body>
</html>
);
}

Replace YOUR_DOMAIN_ID with the value from your dashboard Integration page.

Notify OptSens on route change

Call OptSens.onRouteChange() when the route changes. In the App Router, watch the pathname:

'use client';
import { useEffect } from 'react';
import { usePathname } from 'next/navigation';

export function ConsentRouteSync() {
const pathname = usePathname();
useEffect(() => {
window.OptSens?.onRouteChange();
}, [pathname]);
return null;
}

Render <ConsentRouteSync /> once inside your layout. For a plain React Router app, call it from an effect on location.pathname instead.

Subscribe to consent_update and clean up the listener on unmount. The event replays for late subscribers. This still runs if consent was already given before the component mounted.

'use client';
import { useEffect, useState } from 'react';

export function useAnalyticsConsent() {
const [allowed, setAllowed] = useState(false);
useEffect(() => {
const onUpdate = (consent: { analytics: boolean }) => setAllowed(consent.analytics);
window.OptSens?.on('consent_update', onUpdate);
return () => window.OptSens?.off('consent_update', onUpdate);
}, []);
return allowed;
}

TypeScript note

window.OptSens is added at runtime by the snippet. Declare it for TypeScript to accept the calls:

declare global {
interface Window {
OptSens?: any;
}
}
export {};

Verify

  1. Run the app and open it in a private window. The banner shows on first visit.
  2. Navigate between client-side routes. Confirm the route_change event fires (see Events).
  3. Save a consent choice. Your consent_update listener updates the component.