Skip to content

Commit a51f2ae

Browse files
committed
fix(analytics): improve Google Analytics implementation with dedicated component
- Create dedicated GoogleAnalytics client component with better error handling - Add debug logging and GA4 ID format validation - Update layout to use new GoogleAnalytics component - Improve analytics initialization and error messages
1 parent 20b3a07 commit a51f2ae

File tree

2 files changed

+55
-15
lines changed

2 files changed

+55
-15
lines changed

app/layout.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import React from 'react';
22
import type { Metadata } from 'next';
33
import { Inter } from 'next/font/google';
4-
import Script from 'next/script';
54
import './globals.css';
65
import { config } from '@/lib/config';
76
import { suppressHydrationWarning } from '@/lib/utils/suppress-hydration';
87
import { RootProviders } from './root';
8+
import { GoogleAnalytics } from '@/components/analytics/GoogleAnalytics';
99

1010
const inter = Inter({ subsets: ['latin'] });
1111

@@ -94,20 +94,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
9494
<body className={inter.className} suppressHydrationWarning={true}>
9595
{/* Google Analytics */}
9696
{config.analytics.enabled && config.analytics.id && (
97-
<>
98-
<Script
99-
src={`https://www.googletagmanager.com/gtag/js?id=${config.analytics.id}`}
100-
strategy='afterInteractive'
101-
/>
102-
<Script id='google-analytics' strategy='afterInteractive'>
103-
{`
104-
window.dataLayer = window.dataLayer || [];
105-
function gtag(){dataLayer.push(arguments);}
106-
gtag('js', new Date());
107-
gtag('config', '${config.analytics.id}');
108-
`}
109-
</Script>
110-
</>
97+
<GoogleAnalytics measurementId={config.analytics.id} />
11198
)}
11299
<RootProviders>{children}</RootProviders>
113100
</body>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use client';
2+
3+
import Script from 'next/script';
4+
import { useEffect } from 'react';
5+
6+
interface GoogleAnalyticsProps {
7+
measurementId: string;
8+
}
9+
10+
export function GoogleAnalytics({ measurementId }: GoogleAnalyticsProps) {
11+
useEffect(() => {
12+
// Debug logging (only in development)
13+
if (process.env.NODE_ENV === 'development') {
14+
console.log('[Google Analytics] Initializing with ID:', measurementId);
15+
console.log('[Google Analytics] Script will load from:', `https://www.googletagmanager.com/gtag/js?id=${measurementId}`);
16+
}
17+
}, [measurementId]);
18+
19+
if (!measurementId || measurementId.trim() === '') {
20+
if (process.env.NODE_ENV === 'development') {
21+
console.warn('[Google Analytics] No measurement ID provided. Check your NEXT_PUBLIC_ANALYTICS_ID environment variable.');
22+
}
23+
return null;
24+
}
25+
26+
// Validate GA4 ID format (should start with G-)
27+
if (!measurementId.startsWith('G-')) {
28+
console.warn(
29+
'[Google Analytics] Invalid measurement ID format. GA4 IDs should start with "G-".',
30+
'Current ID:', measurementId
31+
);
32+
}
33+
34+
return (
35+
<>
36+
<Script
37+
src={`https://www.googletagmanager.com/gtag/js?id=${measurementId}`}
38+
strategy='afterInteractive'
39+
/>
40+
<Script id='google-analytics' strategy='afterInteractive'>
41+
{`
42+
window.dataLayer = window.dataLayer || [];
43+
function gtag(){dataLayer.push(arguments);}
44+
gtag('js', new Date());
45+
gtag('config', '${measurementId}', {
46+
page_path: window.location.pathname,
47+
});
48+
`}
49+
</Script>
50+
</>
51+
);
52+
}
53+

0 commit comments

Comments
 (0)