11"use client" ;
22
3- import { useEffect } from "react" ;
4- import { init } from "@plausible-analytics/tracker" ;
3+ import { Suspense , useEffect , useRef } from "react" ;
4+ import { usePathname , useSearchParams } from "next/navigation" ;
5+ import { init , track } from "@plausible-analytics/tracker" ;
56
67/**
7- * Initializes Plausible Analytics on the client side.
8- * Must be rendered within the app to enable tracking.
8+ * Inner component that uses useSearchParams (requires Suspense boundary).
99 */
10- export function PlausibleProvider ( ) {
10+ function PlausibleTracker ( ) {
11+ const pathname = usePathname ( ) ;
12+ const searchParams = useSearchParams ( ) ;
13+ const isInitialized = useRef ( false ) ;
14+
15+ // Initialize Plausible once
1116 useEffect ( ( ) => {
1217 const domain = process . env . NEXT_PUBLIC_PLAUSIBLE_DOMAIN ;
1318
@@ -18,16 +23,48 @@ export function PlausibleProvider() {
1823 return ;
1924 }
2025
21- init ( {
22- domain,
23- // Don't track localhost unless explicitly enabled
24- captureOnLocalhost : process . env . NEXT_PUBLIC_PLAUSIBLE_CAPTURE_LOCALHOST === "true" ,
25- // Track outbound link clicks
26- outboundLinks : true ,
27- // Track file downloads
28- fileDownloads : true ,
29- } ) ;
26+ if ( ! isInitialized . current ) {
27+ init ( {
28+ domain,
29+ // Don't track localhost unless explicitly enabled
30+ captureOnLocalhost : process . env . NEXT_PUBLIC_PLAUSIBLE_CAPTURE_LOCALHOST === "true" ,
31+ // Track outbound link clicks
32+ outboundLinks : true ,
33+ // Track file downloads
34+ fileDownloads : true ,
35+ // Disable auto capture - we handle it manually for Next.js App Router
36+ autoCapturePageviews : false ,
37+ } ) ;
38+ isInitialized . current = true ;
39+ }
3040 } , [ ] ) ;
3141
42+ // Track page views on route changes
43+ useEffect ( ( ) => {
44+ if ( ! process . env . NEXT_PUBLIC_PLAUSIBLE_DOMAIN || ! isInitialized . current ) {
45+ return ;
46+ }
47+
48+ // Build the full URL for tracking
49+ const url = searchParams . toString ( )
50+ ? `${ pathname } ?${ searchParams . toString ( ) } `
51+ : pathname ;
52+
53+ // Track pageview with the current URL
54+ track ( "pageview" , { url } ) ;
55+ } , [ pathname , searchParams ] ) ;
56+
3257 return null ;
3358}
59+
60+ /**
61+ * Initializes Plausible Analytics and tracks page views on route changes.
62+ * Must be rendered within the app to enable tracking.
63+ */
64+ export function PlausibleProvider ( ) {
65+ return (
66+ < Suspense fallback = { null } >
67+ < PlausibleTracker />
68+ </ Suspense >
69+ ) ;
70+ }
0 commit comments