Skip to content

Commit 7c577dd

Browse files
author
Selcuk
committed
Logo emitting, and google analytics
1 parent 9a47176 commit 7c577dd

7 files changed

Lines changed: 561 additions & 15 deletions

File tree

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,23 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next
3434
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
3535

3636
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
37+
38+
## Analytics (Google Analytics 4)
39+
40+
This project supports GA4 to track visits and geography.
41+
42+
1) Create a GA4 property and web data stream. Copy the Measurement ID (looks like `G-XXXXXXX`).
43+
44+
2) Set the environment variable locally or in your hosting provider:
45+
46+
```
47+
NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXX
48+
```
49+
50+
You can use `.env.local` during development. See `.env.local.example`.
51+
52+
3) The app automatically loads GA and tracks route changes. No additional setup is needed.
53+
54+
Notes:
55+
- GA4 reports: Acquisition (source/medium/referrals) and Demographics (country/city).
56+
- GA4 does not identify individual users; data is aggregate. Ensure cookie/consent compliance as required.

src/app/custom-sequence-logo/page.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React from 'react';
44
import CustomSequenceLogo from '@/components/CustomSequenceLogo';
55
import PairwiseOverlapMatrix from '@/components/PairwiseOverlapMatrix';
66
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
7+
import ConsensusEmitter from '@/components/ConsensusEmitter';
78

89
export default function CustomSequenceLogoPage() {
910
// All FASTA files in the custom_msa folder (without .fasta extension)
@@ -56,6 +57,9 @@ export default function CustomSequenceLogoPage() {
5657
</CardContent>
5758
</Card>
5859

60+
{/* Consensus Emitter */}
61+
<ConsensusEmitter customFastaNames={fastaNames} customFolder={folder} />
62+
5963
{/* Pairwise Overlap Matrix */}
6064
<PairwiseOverlapMatrix
6165
fastaNames={fastaNames}

src/app/layout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ThemeProvider } from 'next-themes';
44
import './globals.css';
55
import { TheHeader } from '@/components/TheHeader';
66
import { Toaster } from '@/components/ui/sonner';
7+
import { Analytics } from '@/components/Analytics';
78

89
const openSans = Open_Sans({
910
subsets: ['latin'],
@@ -35,6 +36,7 @@ export default function RootLayout({
3536
<main className="grow">{children}</main>
3637
</ThemeProvider>
3738
<Toaster />
39+
<Analytics />
3840
</body>
3941
</html>
4042
);

src/components/Analytics.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
'use client';
2+
3+
import Script from 'next/script';
4+
import { usePathname, useSearchParams } from 'next/navigation';
5+
import { useEffect } from 'react';
6+
import { GA_MEASUREMENT_ID, trackPageview } from '@/lib/gtag';
7+
8+
export function Analytics() {
9+
const pathname = usePathname();
10+
const searchParams = useSearchParams();
11+
12+
useEffect(() => {
13+
if (!GA_MEASUREMENT_ID) return;
14+
const url = `${pathname}${searchParams?.toString() ? `?${searchParams.toString()}` : ''}`;
15+
trackPageview(url);
16+
// eslint-disable-next-line react-hooks/exhaustive-deps
17+
}, [pathname, searchParams]);
18+
19+
if (!GA_MEASUREMENT_ID) return null;
20+
21+
return (
22+
<>
23+
<Script
24+
src={`https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`}
25+
strategy="afterInteractive"
26+
/>
27+
<Script id="gtag-init" strategy="afterInteractive">
28+
{`
29+
window.dataLayer = window.dataLayer || [];
30+
function gtag(){dataLayer.push(arguments);}
31+
gtag('js', new Date());
32+
gtag('config', '${GA_MEASUREMENT_ID}');
33+
`}
34+
</Script>
35+
</>
36+
);
37+
}
38+
39+

0 commit comments

Comments
 (0)