feat: Add Analytics component with Umami and Clarity support
- Add Analytics.tsx component for tracking with Umami (self-hosted) and Microsoft Clarity - Update layout.tsx to include Analytics component - Environment variables: NEXT_PUBLIC_UMAMI_WEBSITE_ID, NEXT_PUBLIC_CLARITY_ID Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import type { Metadata } from 'next'
|
|||||||
import { Inter } from 'next/font/google'
|
import { Inter } from 'next/font/google'
|
||||||
import './globals.css'
|
import './globals.css'
|
||||||
import ClientLayout from '@/components/ClientLayout'
|
import ClientLayout from '@/components/ClientLayout'
|
||||||
|
import Analytics from '@/components/Analytics'
|
||||||
|
|
||||||
const inter = Inter({ subsets: ['latin'] })
|
const inter = Inter({ subsets: ['latin'] })
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ export default function RootLayout({
|
|||||||
<ClientLayout>
|
<ClientLayout>
|
||||||
{children}
|
{children}
|
||||||
</ClientLayout>
|
</ClientLayout>
|
||||||
|
<Analytics />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
|
|||||||
45
frontend/src/components/Analytics.tsx
Normal file
45
frontend/src/components/Analytics.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import Script from 'next/script';
|
||||||
|
|
||||||
|
interface AnalyticsProps {
|
||||||
|
umamiWebsiteId?: string;
|
||||||
|
umamiSrc?: string;
|
||||||
|
clarityId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Analytics({
|
||||||
|
umamiWebsiteId = process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID,
|
||||||
|
umamiSrc = process.env.NEXT_PUBLIC_UMAMI_SRC || 'https://analytics.grantech.kr/script.js',
|
||||||
|
clarityId = process.env.NEXT_PUBLIC_CLARITY_ID,
|
||||||
|
}: AnalyticsProps) {
|
||||||
|
// Microsoft Clarity initialization
|
||||||
|
useEffect(() => {
|
||||||
|
if (clarityId && typeof window !== 'undefined') {
|
||||||
|
(function (c: Window & { clarity?: Function }, l: Document, a: string, r: string, i: string) {
|
||||||
|
(c as any)[a] = (c as any)[a] || function (...args: any[]) {
|
||||||
|
((c as any)[a].q = (c as any)[a].q || []).push(args);
|
||||||
|
};
|
||||||
|
const t = l.createElement(r) as HTMLScriptElement;
|
||||||
|
t.async = true;
|
||||||
|
t.src = 'https://www.clarity.ms/tag/' + i;
|
||||||
|
const y = l.getElementsByTagName(r)[0];
|
||||||
|
y.parentNode?.insertBefore(t, y);
|
||||||
|
})(window, document, 'clarity', 'script', clarityId);
|
||||||
|
}
|
||||||
|
}, [clarityId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* Umami Analytics */}
|
||||||
|
{umamiWebsiteId && (
|
||||||
|
<Script
|
||||||
|
src={umamiSrc}
|
||||||
|
data-website-id={umamiWebsiteId}
|
||||||
|
strategy="afterInteractive"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user