@@ -21,6 +21,11 @@ const createAppContextPlugin = (context: string) => ({
2121
2222const AMPLITUDE_API_KEY = process . env . NEXT_PUBLIC_AMPLITUDE_API_KEY || '' ;
2323
24+ // Consent version - increment this to force all users to re-consent
25+ const CONSENT_VERSION = 'v1' ;
26+ export const CONSENT_KEY = `userAcceptedAnalytics_${ CONSENT_VERSION } ` ;
27+ const CONSENT_COUNTED_KEY = `analyticsConsentCounted_${ CONSENT_VERSION } ` ;
28+
2429export type TrackEventProperties = {
2530 [ key : string ] : string | number | boolean | Date | undefined ;
2631} ;
@@ -78,7 +83,7 @@ export const createAnalyticsSlice: StateCreator<
7883 eventsTrackingInitialized : false ,
7984
8085 initializeEventsTracking : ( ) => {
81- const userAcceptedAnalytics = localStorage . getItem ( 'userAcceptedAnalytics' ) === 'true' ;
86+ const userAcceptedAnalytics = localStorage . getItem ( CONSENT_KEY ) === 'true' ;
8287 const isInitialized = get ( ) . eventsTrackingInitialized ;
8388
8489 if ( ! AMPLITUDE_API_KEY ) return ;
@@ -120,18 +125,65 @@ export const createAnalyticsSlice: StateCreator<
120125 }
121126 } ,
122127 acceptAnalytics : ( ) => {
123- localStorage . setItem ( 'userAcceptedAnalytics' , 'true' ) ;
128+ localStorage . setItem ( CONSENT_KEY , 'true' ) ;
124129 set ( { isTrackingEnabled : true , analyticsConfigOpen : false } ) ;
125130
126131 get ( ) . initializeEventsTracking ( ) ;
132+
133+ // Only track the consent event once per user per consent version
134+ const alreadyCounted = localStorage . getItem ( CONSENT_COUNTED_KEY ) === 'true' ;
135+ if ( ! alreadyCounted ) {
136+ localStorage . setItem ( CONSENT_COUNTED_KEY , 'true' ) ;
137+ get ( ) . trackEvent ( 'analytics_consent_given' ) ;
138+ }
127139 } ,
128140 rejectAnalytics : ( ) => {
129- localStorage . setItem ( 'userAcceptedAnalytics' , 'false' ) ;
141+ localStorage . setItem ( CONSENT_KEY , 'false' ) ;
142+
143+ // Only track the consent event once per user per consent version
144+ const alreadyCounted = localStorage . getItem ( CONSENT_COUNTED_KEY ) === 'true' ;
145+
146+ if ( ! alreadyCounted && AMPLITUDE_API_KEY ) {
147+ localStorage . setItem ( CONSENT_COUNTED_KEY , 'true' ) ;
148+
149+ if ( ! get ( ) . eventsTrackingInitialized ) {
150+ // Initialize minimal tracking just for this one event
151+ init ( AMPLITUDE_API_KEY , {
152+ autocapture : false ,
153+ trackingOptions : {
154+ ipAddress : false ,
155+ language : false ,
156+ platform : false ,
157+ } ,
158+ } ) ;
159+ add ( createAppContextPlugin ( 'app' ) ) ;
160+ set ( { eventsTrackingInitialized : true } ) ;
161+ }
162+
163+ try {
164+ // Temporarily enable tracking to send the opt-out event
165+ // This ensures the event is sent even if Amplitude is in opt-out mode
166+ setOptOut ( false ) ;
167+
168+ track ( 'analytics_consent_declined' , {
169+ app_context : 'app' ,
170+ } ) ;
171+
172+ // Immediately disable tracking again
173+ setOptOut ( true ) ;
174+ } catch ( err ) {
175+ console . log ( 'Error tracking opt-out event' , err ) ;
176+ }
177+ }
178+
179+ // Now disable all tracking
130180 setOptOut ( true ) ;
131181 set ( { isTrackingEnabled : false , analyticsConfigOpen : false } ) ;
132182 } ,
133183 setAnalyticsConfigOpen : ( value : boolean ) => {
134- localStorage . removeItem ( 'userAcceptedAnalytics' ) ;
184+ // Clear the current consent version when reopening analytics config
185+ localStorage . removeItem ( CONSENT_KEY ) ;
186+ localStorage . removeItem ( CONSENT_COUNTED_KEY ) ;
135187
136188 set ( { analyticsConfigOpen : value } ) ;
137189 } ,
0 commit comments