@jwiedeman/gtm-kit-react 1.1.6 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -9
- package/dist/index.cjs +240 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +306 -3
- package/dist/index.d.ts +306 -3
- package/dist/index.js +230 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,56 @@
|
|
|
1
|
-
import { PropsWithChildren, JSX } from 'react';
|
|
1
|
+
import { PropsWithChildren, JSX, ReactNode, ErrorInfo, Component } from 'react';
|
|
2
2
|
import { CreateGtmClientOptions, GtmClient, DataLayerValue, ConsentState, ConsentRegionOptions, ScriptLoadState } from '@jwiedeman/gtm-kit';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Check if code is running in a server-side rendering environment.
|
|
6
|
+
* Returns true if window is undefined (Node.js/SSR), false in browser.
|
|
7
|
+
*/
|
|
8
|
+
declare const isSsr: () => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Hook that returns false during SSR and initial hydration, then true after hydration completes.
|
|
11
|
+
* Use this to prevent hydration mismatches when rendering GTM-dependent content.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const isHydrated = useHydrated();
|
|
16
|
+
*
|
|
17
|
+
* // Safe: won't cause hydration mismatch
|
|
18
|
+
* return isHydrated ? <DynamicContent /> : <StaticPlaceholder />;
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare const useHydrated: () => boolean;
|
|
4
22
|
interface GtmProviderProps extends PropsWithChildren {
|
|
5
23
|
config: CreateGtmClientOptions;
|
|
24
|
+
/**
|
|
25
|
+
* Callback executed before GTM initialization.
|
|
26
|
+
* Use this to set consent defaults.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <GtmProvider
|
|
31
|
+
* config={{ containers: 'GTM-XXXXXX' }}
|
|
32
|
+
* onBeforeInit={(client) => {
|
|
33
|
+
* client.setConsentDefaults({
|
|
34
|
+
* ad_storage: 'denied',
|
|
35
|
+
* analytics_storage: 'denied'
|
|
36
|
+
* });
|
|
37
|
+
* }}
|
|
38
|
+
* >
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
onBeforeInit?: (client: GtmClient) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Callback executed after GTM initialization.
|
|
44
|
+
*/
|
|
45
|
+
onAfterInit?: (client: GtmClient) => void;
|
|
6
46
|
}
|
|
7
47
|
interface GtmContextValue {
|
|
8
48
|
client: GtmClient;
|
|
9
49
|
push: (value: DataLayerValue) => void;
|
|
10
50
|
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
11
51
|
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
52
|
+
/** Synchronously check if all GTM scripts have finished loading */
|
|
53
|
+
isReady: () => boolean;
|
|
12
54
|
whenReady: () => Promise<ScriptLoadState[]>;
|
|
13
55
|
onReady: (callback: (state: ScriptLoadState[]) => void) => () => void;
|
|
14
56
|
}
|
|
@@ -16,11 +58,272 @@ interface GtmConsentApi {
|
|
|
16
58
|
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
17
59
|
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
18
60
|
}
|
|
19
|
-
|
|
61
|
+
/**
|
|
62
|
+
* GTM Provider component that initializes Google Tag Manager for your React app.
|
|
63
|
+
*
|
|
64
|
+
* ## SSR/Hydration Behavior
|
|
65
|
+
*
|
|
66
|
+
* This provider is SSR-safe and handles hydration correctly:
|
|
67
|
+
* - **Server**: No GTM initialization occurs (no window/document access)
|
|
68
|
+
* - **Client Hydration**: GTM initializes only after hydration via useEffect
|
|
69
|
+
* - **No Hydration Mismatch**: Provider renders the same on server and client
|
|
70
|
+
*
|
|
71
|
+
* ## Usage with SSR Frameworks
|
|
72
|
+
*
|
|
73
|
+
* ```tsx
|
|
74
|
+
* // Next.js, Remix, etc.
|
|
75
|
+
* export default function App({ children }) {
|
|
76
|
+
* return (
|
|
77
|
+
* <GtmProvider config={{ containers: 'GTM-XXXXXX' }}>
|
|
78
|
+
* {children}
|
|
79
|
+
* </GtmProvider>
|
|
80
|
+
* );
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* ## Preventing Hydration Mismatches
|
|
85
|
+
*
|
|
86
|
+
* If you render different content based on GTM state, use `useHydrated`:
|
|
87
|
+
*
|
|
88
|
+
* ```tsx
|
|
89
|
+
* const isHydrated = useHydrated();
|
|
90
|
+
* const isGtmReady = useGtmInitialized();
|
|
91
|
+
*
|
|
92
|
+
* // Safe: both server and client initially render the placeholder
|
|
93
|
+
* if (!isHydrated) return <Placeholder />;
|
|
94
|
+
* return isGtmReady ? <TrackedContent /> : <LoadingContent />;
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare const GtmProvider: ({ config, children, onBeforeInit, onAfterInit }: GtmProviderProps) => JSX.Element;
|
|
98
|
+
/**
|
|
99
|
+
* Hook to access the full GTM context. Throws if used outside GtmProvider.
|
|
100
|
+
*
|
|
101
|
+
* For most use cases, prefer the specific hooks:
|
|
102
|
+
* - `useGtmPush()` - Push events to dataLayer
|
|
103
|
+
* - `useGtmConsent()` - Manage consent state
|
|
104
|
+
* - `useGtmClient()` - Access the raw GTM client
|
|
105
|
+
*
|
|
106
|
+
* @throws Error if called outside of GtmProvider
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```tsx
|
|
110
|
+
* const { push, client, isReady, whenReady } = useGtm();
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
20
113
|
declare const useGtm: () => GtmContextValue;
|
|
114
|
+
/**
|
|
115
|
+
* Hook to check if GtmProvider is present without throwing.
|
|
116
|
+
*
|
|
117
|
+
* Useful for components that may be rendered before the provider mounts,
|
|
118
|
+
* or for optional GTM integration.
|
|
119
|
+
*
|
|
120
|
+
* @returns `true` if inside GtmProvider, `false` otherwise
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```tsx
|
|
124
|
+
* const hasProvider = useIsGtmProviderPresent();
|
|
125
|
+
*
|
|
126
|
+
* const handleClick = () => {
|
|
127
|
+
* if (hasProvider) {
|
|
128
|
+
* // Safe to use GTM hooks
|
|
129
|
+
* }
|
|
130
|
+
* };
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
declare const useIsGtmProviderPresent: () => boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Hook to access the raw GTM client instance.
|
|
136
|
+
*
|
|
137
|
+
* @throws Error if called outside of GtmProvider
|
|
138
|
+
* @returns The GTM client instance
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```tsx
|
|
142
|
+
* const client = useGtmClient();
|
|
143
|
+
*
|
|
144
|
+
* // Access low-level APIs
|
|
145
|
+
* const diagnostics = client.getDiagnostics();
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
21
148
|
declare const useGtmClient: () => GtmClient;
|
|
149
|
+
/**
|
|
150
|
+
* Hook to get the push function for sending events to the dataLayer.
|
|
151
|
+
*
|
|
152
|
+
* This is the most commonly used hook for tracking events.
|
|
153
|
+
*
|
|
154
|
+
* @throws Error if called outside of GtmProvider
|
|
155
|
+
* @returns Function to push values to the dataLayer
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```tsx
|
|
159
|
+
* const push = useGtmPush();
|
|
160
|
+
*
|
|
161
|
+
* const handleAddToCart = (product) => {
|
|
162
|
+
* push({
|
|
163
|
+
* event: 'add_to_cart',
|
|
164
|
+
* ecommerce: {
|
|
165
|
+
* items: [{ item_id: product.id, item_name: product.name }]
|
|
166
|
+
* }
|
|
167
|
+
* });
|
|
168
|
+
* };
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
22
171
|
declare const useGtmPush: () => ((value: DataLayerValue) => void);
|
|
172
|
+
/**
|
|
173
|
+
* Hook to access consent management functions.
|
|
174
|
+
*
|
|
175
|
+
* @throws Error if called outside of GtmProvider
|
|
176
|
+
* @returns Object with `setConsentDefaults` and `updateConsent` functions
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```tsx
|
|
180
|
+
* const { updateConsent } = useGtmConsent();
|
|
181
|
+
*
|
|
182
|
+
* const handleAcceptCookies = () => {
|
|
183
|
+
* updateConsent({
|
|
184
|
+
* ad_storage: 'granted',
|
|
185
|
+
* analytics_storage: 'granted'
|
|
186
|
+
* });
|
|
187
|
+
* };
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
23
190
|
declare const useGtmConsent: () => GtmConsentApi;
|
|
191
|
+
/**
|
|
192
|
+
* Hook that returns the `whenReady` promise function.
|
|
193
|
+
*
|
|
194
|
+
* **When to use**: When you need to await GTM script loading before taking an action.
|
|
195
|
+
* The returned function returns a Promise that resolves when scripts finish loading.
|
|
196
|
+
*
|
|
197
|
+
* **Comparison of GTM readiness hooks:**
|
|
198
|
+
* | Hook | Returns | Re-renders | Use Case |
|
|
199
|
+
* |------|---------|------------|----------|
|
|
200
|
+
* | `useGtmReady()` | `() => Promise` | No | Await in event handlers |
|
|
201
|
+
* | `useIsGtmReady()` | `() => boolean` | No | Synchronous checks in callbacks |
|
|
202
|
+
* | `useGtmInitialized()` | `boolean` | Yes | Conditional rendering |
|
|
203
|
+
*
|
|
204
|
+
* @returns Function that returns a Promise resolving to script load states
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```tsx
|
|
208
|
+
* const whenReady = useGtmReady();
|
|
209
|
+
*
|
|
210
|
+
* const handleClick = async () => {
|
|
211
|
+
* const states = await whenReady();
|
|
212
|
+
* if (states.every(s => s.status === 'loaded')) {
|
|
213
|
+
* // Safe to rely on GTM being fully loaded
|
|
214
|
+
* }
|
|
215
|
+
* };
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
24
218
|
declare const useGtmReady: () => (() => Promise<ScriptLoadState[]>);
|
|
219
|
+
/**
|
|
220
|
+
* Hook that returns a function to synchronously check if GTM is ready.
|
|
221
|
+
*
|
|
222
|
+
* **When to use**: When you need to check readiness without triggering re-renders,
|
|
223
|
+
* typically in event handlers or callbacks.
|
|
224
|
+
*
|
|
225
|
+
* **Comparison of GTM readiness hooks:**
|
|
226
|
+
* | Hook | Returns | Re-renders | Use Case |
|
|
227
|
+
* |------|---------|------------|----------|
|
|
228
|
+
* | `useGtmReady()` | `() => Promise` | No | Await in event handlers |
|
|
229
|
+
* | `useIsGtmReady()` | `() => boolean` | No | Synchronous checks in callbacks |
|
|
230
|
+
* | `useGtmInitialized()` | `boolean` | Yes | Conditional rendering |
|
|
231
|
+
*
|
|
232
|
+
* @returns Function that returns `true` if scripts loaded, `false` if still loading
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```tsx
|
|
236
|
+
* const checkReady = useIsGtmReady();
|
|
237
|
+
*
|
|
238
|
+
* const handleSubmit = () => {
|
|
239
|
+
* if (checkReady()) {
|
|
240
|
+
* // GTM is ready, proceed with tracking
|
|
241
|
+
* push({ event: 'form_submit' });
|
|
242
|
+
* }
|
|
243
|
+
* };
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
declare const useIsGtmReady: () => (() => boolean);
|
|
247
|
+
/**
|
|
248
|
+
* Reactive hook that returns `true` when GTM scripts have finished loading.
|
|
249
|
+
*
|
|
250
|
+
* **When to use**: When you need to conditionally render UI based on GTM readiness.
|
|
251
|
+
* This hook triggers a re-render when the state changes.
|
|
252
|
+
*
|
|
253
|
+
* **Comparison of GTM readiness hooks:**
|
|
254
|
+
* | Hook | Returns | Re-renders | Use Case |
|
|
255
|
+
* |------|---------|------------|----------|
|
|
256
|
+
* | `useGtmReady()` | `() => Promise` | No | Await in event handlers |
|
|
257
|
+
* | `useIsGtmReady()` | `() => boolean` | No | Synchronous checks in callbacks |
|
|
258
|
+
* | `useGtmInitialized()` | `boolean` | Yes | Conditional rendering |
|
|
259
|
+
*
|
|
260
|
+
* @returns `true` if GTM is initialized, `false` otherwise (reactive)
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```tsx
|
|
264
|
+
* const isInitialized = useGtmInitialized();
|
|
265
|
+
*
|
|
266
|
+
* if (!isInitialized) {
|
|
267
|
+
* return <LoadingSpinner />;
|
|
268
|
+
* }
|
|
269
|
+
*
|
|
270
|
+
* return <AnalyticsDashboard />;
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
declare const useGtmInitialized: () => boolean;
|
|
274
|
+
/**
|
|
275
|
+
* Result from the useGtmError hook.
|
|
276
|
+
*/
|
|
277
|
+
interface GtmErrorState {
|
|
278
|
+
/** Whether any scripts failed to load */
|
|
279
|
+
hasError: boolean;
|
|
280
|
+
/** Array of failed script states (status 'failed' or 'partial') */
|
|
281
|
+
failedScripts: ScriptLoadState[];
|
|
282
|
+
/** Convenience getter for the first error message, if any */
|
|
283
|
+
errorMessage: string | null;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Hook to capture GTM script load errors.
|
|
287
|
+
* Returns reactive state that updates when scripts fail to load.
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* ```tsx
|
|
291
|
+
* const { hasError, failedScripts, errorMessage } = useGtmError();
|
|
292
|
+
*
|
|
293
|
+
* if (hasError) {
|
|
294
|
+
* console.error('GTM failed to load:', errorMessage);
|
|
295
|
+
* // Optionally show fallback UI or retry logic
|
|
296
|
+
* }
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
declare const useGtmError: () => GtmErrorState;
|
|
300
|
+
/**
|
|
301
|
+
* Props for GtmErrorBoundary component.
|
|
302
|
+
*/
|
|
303
|
+
interface GtmErrorBoundaryProps {
|
|
304
|
+
children: ReactNode;
|
|
305
|
+
/** Fallback UI to render when an error occurs */
|
|
306
|
+
fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
|
|
307
|
+
/** Callback invoked when an error is caught */
|
|
308
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
309
|
+
/** Whether to log errors to console (default: true in development) */
|
|
310
|
+
logErrors?: boolean;
|
|
311
|
+
}
|
|
312
|
+
interface GtmErrorBoundaryState {
|
|
313
|
+
hasError: boolean;
|
|
314
|
+
error: Error | null;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Error boundary component for GTM provider.
|
|
318
|
+
* Catches errors during GTM initialization and renders a fallback UI.
|
|
319
|
+
* Analytics and tracking will be disabled when an error occurs.
|
|
320
|
+
*/
|
|
321
|
+
declare class GtmErrorBoundary extends Component<GtmErrorBoundaryProps, GtmErrorBoundaryState> {
|
|
322
|
+
constructor(props: GtmErrorBoundaryProps);
|
|
323
|
+
static getDerivedStateFromError(error: Error): GtmErrorBoundaryState;
|
|
324
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
325
|
+
reset: () => void;
|
|
326
|
+
render(): ReactNode;
|
|
327
|
+
}
|
|
25
328
|
|
|
26
|
-
export { GtmConsentApi, GtmContextValue, GtmProvider, GtmProviderProps, useGtm, useGtmClient, useGtmConsent, useGtmPush, useGtmReady };
|
|
329
|
+
export { GtmConsentApi, GtmContextValue, GtmErrorBoundary, GtmErrorBoundaryProps, GtmErrorState, GtmProvider, GtmProviderProps, isSsr, useGtm, useGtmClient, useGtmConsent, useGtmError, useGtmInitialized, useGtmPush, useGtmReady, useHydrated, useIsGtmProviderPresent, useIsGtmReady };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,56 @@
|
|
|
1
|
-
import { PropsWithChildren, JSX } from 'react';
|
|
1
|
+
import { PropsWithChildren, JSX, ReactNode, ErrorInfo, Component } from 'react';
|
|
2
2
|
import { CreateGtmClientOptions, GtmClient, DataLayerValue, ConsentState, ConsentRegionOptions, ScriptLoadState } from '@jwiedeman/gtm-kit';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Check if code is running in a server-side rendering environment.
|
|
6
|
+
* Returns true if window is undefined (Node.js/SSR), false in browser.
|
|
7
|
+
*/
|
|
8
|
+
declare const isSsr: () => boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Hook that returns false during SSR and initial hydration, then true after hydration completes.
|
|
11
|
+
* Use this to prevent hydration mismatches when rendering GTM-dependent content.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* const isHydrated = useHydrated();
|
|
16
|
+
*
|
|
17
|
+
* // Safe: won't cause hydration mismatch
|
|
18
|
+
* return isHydrated ? <DynamicContent /> : <StaticPlaceholder />;
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
declare const useHydrated: () => boolean;
|
|
4
22
|
interface GtmProviderProps extends PropsWithChildren {
|
|
5
23
|
config: CreateGtmClientOptions;
|
|
24
|
+
/**
|
|
25
|
+
* Callback executed before GTM initialization.
|
|
26
|
+
* Use this to set consent defaults.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <GtmProvider
|
|
31
|
+
* config={{ containers: 'GTM-XXXXXX' }}
|
|
32
|
+
* onBeforeInit={(client) => {
|
|
33
|
+
* client.setConsentDefaults({
|
|
34
|
+
* ad_storage: 'denied',
|
|
35
|
+
* analytics_storage: 'denied'
|
|
36
|
+
* });
|
|
37
|
+
* }}
|
|
38
|
+
* >
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
onBeforeInit?: (client: GtmClient) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Callback executed after GTM initialization.
|
|
44
|
+
*/
|
|
45
|
+
onAfterInit?: (client: GtmClient) => void;
|
|
6
46
|
}
|
|
7
47
|
interface GtmContextValue {
|
|
8
48
|
client: GtmClient;
|
|
9
49
|
push: (value: DataLayerValue) => void;
|
|
10
50
|
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
11
51
|
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
52
|
+
/** Synchronously check if all GTM scripts have finished loading */
|
|
53
|
+
isReady: () => boolean;
|
|
12
54
|
whenReady: () => Promise<ScriptLoadState[]>;
|
|
13
55
|
onReady: (callback: (state: ScriptLoadState[]) => void) => () => void;
|
|
14
56
|
}
|
|
@@ -16,11 +58,272 @@ interface GtmConsentApi {
|
|
|
16
58
|
setConsentDefaults: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
17
59
|
updateConsent: (state: ConsentState, options?: ConsentRegionOptions) => void;
|
|
18
60
|
}
|
|
19
|
-
|
|
61
|
+
/**
|
|
62
|
+
* GTM Provider component that initializes Google Tag Manager for your React app.
|
|
63
|
+
*
|
|
64
|
+
* ## SSR/Hydration Behavior
|
|
65
|
+
*
|
|
66
|
+
* This provider is SSR-safe and handles hydration correctly:
|
|
67
|
+
* - **Server**: No GTM initialization occurs (no window/document access)
|
|
68
|
+
* - **Client Hydration**: GTM initializes only after hydration via useEffect
|
|
69
|
+
* - **No Hydration Mismatch**: Provider renders the same on server and client
|
|
70
|
+
*
|
|
71
|
+
* ## Usage with SSR Frameworks
|
|
72
|
+
*
|
|
73
|
+
* ```tsx
|
|
74
|
+
* // Next.js, Remix, etc.
|
|
75
|
+
* export default function App({ children }) {
|
|
76
|
+
* return (
|
|
77
|
+
* <GtmProvider config={{ containers: 'GTM-XXXXXX' }}>
|
|
78
|
+
* {children}
|
|
79
|
+
* </GtmProvider>
|
|
80
|
+
* );
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* ## Preventing Hydration Mismatches
|
|
85
|
+
*
|
|
86
|
+
* If you render different content based on GTM state, use `useHydrated`:
|
|
87
|
+
*
|
|
88
|
+
* ```tsx
|
|
89
|
+
* const isHydrated = useHydrated();
|
|
90
|
+
* const isGtmReady = useGtmInitialized();
|
|
91
|
+
*
|
|
92
|
+
* // Safe: both server and client initially render the placeholder
|
|
93
|
+
* if (!isHydrated) return <Placeholder />;
|
|
94
|
+
* return isGtmReady ? <TrackedContent /> : <LoadingContent />;
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare const GtmProvider: ({ config, children, onBeforeInit, onAfterInit }: GtmProviderProps) => JSX.Element;
|
|
98
|
+
/**
|
|
99
|
+
* Hook to access the full GTM context. Throws if used outside GtmProvider.
|
|
100
|
+
*
|
|
101
|
+
* For most use cases, prefer the specific hooks:
|
|
102
|
+
* - `useGtmPush()` - Push events to dataLayer
|
|
103
|
+
* - `useGtmConsent()` - Manage consent state
|
|
104
|
+
* - `useGtmClient()` - Access the raw GTM client
|
|
105
|
+
*
|
|
106
|
+
* @throws Error if called outside of GtmProvider
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```tsx
|
|
110
|
+
* const { push, client, isReady, whenReady } = useGtm();
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
20
113
|
declare const useGtm: () => GtmContextValue;
|
|
114
|
+
/**
|
|
115
|
+
* Hook to check if GtmProvider is present without throwing.
|
|
116
|
+
*
|
|
117
|
+
* Useful for components that may be rendered before the provider mounts,
|
|
118
|
+
* or for optional GTM integration.
|
|
119
|
+
*
|
|
120
|
+
* @returns `true` if inside GtmProvider, `false` otherwise
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```tsx
|
|
124
|
+
* const hasProvider = useIsGtmProviderPresent();
|
|
125
|
+
*
|
|
126
|
+
* const handleClick = () => {
|
|
127
|
+
* if (hasProvider) {
|
|
128
|
+
* // Safe to use GTM hooks
|
|
129
|
+
* }
|
|
130
|
+
* };
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
declare const useIsGtmProviderPresent: () => boolean;
|
|
134
|
+
/**
|
|
135
|
+
* Hook to access the raw GTM client instance.
|
|
136
|
+
*
|
|
137
|
+
* @throws Error if called outside of GtmProvider
|
|
138
|
+
* @returns The GTM client instance
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```tsx
|
|
142
|
+
* const client = useGtmClient();
|
|
143
|
+
*
|
|
144
|
+
* // Access low-level APIs
|
|
145
|
+
* const diagnostics = client.getDiagnostics();
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
21
148
|
declare const useGtmClient: () => GtmClient;
|
|
149
|
+
/**
|
|
150
|
+
* Hook to get the push function for sending events to the dataLayer.
|
|
151
|
+
*
|
|
152
|
+
* This is the most commonly used hook for tracking events.
|
|
153
|
+
*
|
|
154
|
+
* @throws Error if called outside of GtmProvider
|
|
155
|
+
* @returns Function to push values to the dataLayer
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```tsx
|
|
159
|
+
* const push = useGtmPush();
|
|
160
|
+
*
|
|
161
|
+
* const handleAddToCart = (product) => {
|
|
162
|
+
* push({
|
|
163
|
+
* event: 'add_to_cart',
|
|
164
|
+
* ecommerce: {
|
|
165
|
+
* items: [{ item_id: product.id, item_name: product.name }]
|
|
166
|
+
* }
|
|
167
|
+
* });
|
|
168
|
+
* };
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
22
171
|
declare const useGtmPush: () => ((value: DataLayerValue) => void);
|
|
172
|
+
/**
|
|
173
|
+
* Hook to access consent management functions.
|
|
174
|
+
*
|
|
175
|
+
* @throws Error if called outside of GtmProvider
|
|
176
|
+
* @returns Object with `setConsentDefaults` and `updateConsent` functions
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```tsx
|
|
180
|
+
* const { updateConsent } = useGtmConsent();
|
|
181
|
+
*
|
|
182
|
+
* const handleAcceptCookies = () => {
|
|
183
|
+
* updateConsent({
|
|
184
|
+
* ad_storage: 'granted',
|
|
185
|
+
* analytics_storage: 'granted'
|
|
186
|
+
* });
|
|
187
|
+
* };
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
23
190
|
declare const useGtmConsent: () => GtmConsentApi;
|
|
191
|
+
/**
|
|
192
|
+
* Hook that returns the `whenReady` promise function.
|
|
193
|
+
*
|
|
194
|
+
* **When to use**: When you need to await GTM script loading before taking an action.
|
|
195
|
+
* The returned function returns a Promise that resolves when scripts finish loading.
|
|
196
|
+
*
|
|
197
|
+
* **Comparison of GTM readiness hooks:**
|
|
198
|
+
* | Hook | Returns | Re-renders | Use Case |
|
|
199
|
+
* |------|---------|------------|----------|
|
|
200
|
+
* | `useGtmReady()` | `() => Promise` | No | Await in event handlers |
|
|
201
|
+
* | `useIsGtmReady()` | `() => boolean` | No | Synchronous checks in callbacks |
|
|
202
|
+
* | `useGtmInitialized()` | `boolean` | Yes | Conditional rendering |
|
|
203
|
+
*
|
|
204
|
+
* @returns Function that returns a Promise resolving to script load states
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```tsx
|
|
208
|
+
* const whenReady = useGtmReady();
|
|
209
|
+
*
|
|
210
|
+
* const handleClick = async () => {
|
|
211
|
+
* const states = await whenReady();
|
|
212
|
+
* if (states.every(s => s.status === 'loaded')) {
|
|
213
|
+
* // Safe to rely on GTM being fully loaded
|
|
214
|
+
* }
|
|
215
|
+
* };
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
24
218
|
declare const useGtmReady: () => (() => Promise<ScriptLoadState[]>);
|
|
219
|
+
/**
|
|
220
|
+
* Hook that returns a function to synchronously check if GTM is ready.
|
|
221
|
+
*
|
|
222
|
+
* **When to use**: When you need to check readiness without triggering re-renders,
|
|
223
|
+
* typically in event handlers or callbacks.
|
|
224
|
+
*
|
|
225
|
+
* **Comparison of GTM readiness hooks:**
|
|
226
|
+
* | Hook | Returns | Re-renders | Use Case |
|
|
227
|
+
* |------|---------|------------|----------|
|
|
228
|
+
* | `useGtmReady()` | `() => Promise` | No | Await in event handlers |
|
|
229
|
+
* | `useIsGtmReady()` | `() => boolean` | No | Synchronous checks in callbacks |
|
|
230
|
+
* | `useGtmInitialized()` | `boolean` | Yes | Conditional rendering |
|
|
231
|
+
*
|
|
232
|
+
* @returns Function that returns `true` if scripts loaded, `false` if still loading
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```tsx
|
|
236
|
+
* const checkReady = useIsGtmReady();
|
|
237
|
+
*
|
|
238
|
+
* const handleSubmit = () => {
|
|
239
|
+
* if (checkReady()) {
|
|
240
|
+
* // GTM is ready, proceed with tracking
|
|
241
|
+
* push({ event: 'form_submit' });
|
|
242
|
+
* }
|
|
243
|
+
* };
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
declare const useIsGtmReady: () => (() => boolean);
|
|
247
|
+
/**
|
|
248
|
+
* Reactive hook that returns `true` when GTM scripts have finished loading.
|
|
249
|
+
*
|
|
250
|
+
* **When to use**: When you need to conditionally render UI based on GTM readiness.
|
|
251
|
+
* This hook triggers a re-render when the state changes.
|
|
252
|
+
*
|
|
253
|
+
* **Comparison of GTM readiness hooks:**
|
|
254
|
+
* | Hook | Returns | Re-renders | Use Case |
|
|
255
|
+
* |------|---------|------------|----------|
|
|
256
|
+
* | `useGtmReady()` | `() => Promise` | No | Await in event handlers |
|
|
257
|
+
* | `useIsGtmReady()` | `() => boolean` | No | Synchronous checks in callbacks |
|
|
258
|
+
* | `useGtmInitialized()` | `boolean` | Yes | Conditional rendering |
|
|
259
|
+
*
|
|
260
|
+
* @returns `true` if GTM is initialized, `false` otherwise (reactive)
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```tsx
|
|
264
|
+
* const isInitialized = useGtmInitialized();
|
|
265
|
+
*
|
|
266
|
+
* if (!isInitialized) {
|
|
267
|
+
* return <LoadingSpinner />;
|
|
268
|
+
* }
|
|
269
|
+
*
|
|
270
|
+
* return <AnalyticsDashboard />;
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
declare const useGtmInitialized: () => boolean;
|
|
274
|
+
/**
|
|
275
|
+
* Result from the useGtmError hook.
|
|
276
|
+
*/
|
|
277
|
+
interface GtmErrorState {
|
|
278
|
+
/** Whether any scripts failed to load */
|
|
279
|
+
hasError: boolean;
|
|
280
|
+
/** Array of failed script states (status 'failed' or 'partial') */
|
|
281
|
+
failedScripts: ScriptLoadState[];
|
|
282
|
+
/** Convenience getter for the first error message, if any */
|
|
283
|
+
errorMessage: string | null;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Hook to capture GTM script load errors.
|
|
287
|
+
* Returns reactive state that updates when scripts fail to load.
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* ```tsx
|
|
291
|
+
* const { hasError, failedScripts, errorMessage } = useGtmError();
|
|
292
|
+
*
|
|
293
|
+
* if (hasError) {
|
|
294
|
+
* console.error('GTM failed to load:', errorMessage);
|
|
295
|
+
* // Optionally show fallback UI or retry logic
|
|
296
|
+
* }
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
declare const useGtmError: () => GtmErrorState;
|
|
300
|
+
/**
|
|
301
|
+
* Props for GtmErrorBoundary component.
|
|
302
|
+
*/
|
|
303
|
+
interface GtmErrorBoundaryProps {
|
|
304
|
+
children: ReactNode;
|
|
305
|
+
/** Fallback UI to render when an error occurs */
|
|
306
|
+
fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
|
|
307
|
+
/** Callback invoked when an error is caught */
|
|
308
|
+
onError?: (error: Error, errorInfo: ErrorInfo) => void;
|
|
309
|
+
/** Whether to log errors to console (default: true in development) */
|
|
310
|
+
logErrors?: boolean;
|
|
311
|
+
}
|
|
312
|
+
interface GtmErrorBoundaryState {
|
|
313
|
+
hasError: boolean;
|
|
314
|
+
error: Error | null;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Error boundary component for GTM provider.
|
|
318
|
+
* Catches errors during GTM initialization and renders a fallback UI.
|
|
319
|
+
* Analytics and tracking will be disabled when an error occurs.
|
|
320
|
+
*/
|
|
321
|
+
declare class GtmErrorBoundary extends Component<GtmErrorBoundaryProps, GtmErrorBoundaryState> {
|
|
322
|
+
constructor(props: GtmErrorBoundaryProps);
|
|
323
|
+
static getDerivedStateFromError(error: Error): GtmErrorBoundaryState;
|
|
324
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
325
|
+
reset: () => void;
|
|
326
|
+
render(): ReactNode;
|
|
327
|
+
}
|
|
25
328
|
|
|
26
|
-
export { GtmConsentApi, GtmContextValue, GtmProvider, GtmProviderProps, useGtm, useGtmClient, useGtmConsent, useGtmPush, useGtmReady };
|
|
329
|
+
export { GtmConsentApi, GtmContextValue, GtmErrorBoundary, GtmErrorBoundaryProps, GtmErrorState, GtmProvider, GtmProviderProps, isSsr, useGtm, useGtmClient, useGtmConsent, useGtmError, useGtmInitialized, useGtmPush, useGtmReady, useHydrated, useIsGtmProviderPresent, useIsGtmReady };
|