Skip to content

Commit 4605ee9

Browse files
committed
docs: enhance analytics integration
1 parent b939db9 commit 4605ee9

File tree

8 files changed

+79
-13
lines changed

8 files changed

+79
-13
lines changed

docs/instrumentation-client.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ import posthog from "posthog-js";
22

33
if (typeof window !== "undefined") {
44
const apiKey = process.env.NEXT_PUBLIC_POSTHOG_KEY;
5+
const CONSENT_KEY = "funnel-analytics-consent";
56

67
if (apiKey) {
8+
const consent = localStorage.getItem(CONSENT_KEY);
9+
const hasAccepted = consent === "accepted";
10+
711
posthog.init(apiKey, {
812
api_host: "/ingest",
913
ui_host: "https://eu.posthog.com",
@@ -18,6 +22,11 @@ if (typeof window !== "undefined") {
1822
css_selector_allowlist: ["[data-track]", "button", "a[href]"],
1923
dom_event_allowlist: ["click", "submit"],
2024
},
25+
opt_out_capturing_by_default: true,
2126
});
27+
28+
if (hasAccepted) {
29+
posthog.opt_in_capturing();
30+
}
2231
}
2332
}

docs/src/app/(home)/layout.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
import type { ReactNode } from 'react';
2-
import { HomeLayout } from 'fumadocs-ui/layouts/home';
3-
import { baseOptions } from '@/app/layout.config';
1+
import type { ReactNode } from "react";
2+
import { HomeLayout } from "fumadocs-ui/layouts/home";
3+
import { baseOptions } from "@/app/layout.config";
4+
import { Footer } from "@/components/layout/footer";
45

56
export default function Layout({ children }: { children: ReactNode }) {
6-
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
7+
return (
8+
<>
9+
<HomeLayout {...baseOptions}>{children}</HomeLayout>
10+
<Footer />
11+
</>
12+
);
713
}

docs/src/app/(legal)/layout.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import type { ReactNode } from "react";
2+
import { Footer } from "@/components/layout/footer";
3+
4+
export default function LegalLayout({ children }: { children: ReactNode }) {
5+
return (
6+
<>
7+
{children}
8+
<Footer />
9+
</>
10+
);
11+
}

docs/src/app/docs/layout.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { DocsLayout, type DocsLayoutProps } from "fumadocs-ui/layouts/docs";
22
import type { ReactNode } from "react";
33
import { baseOptions } from "@/app/layout.config";
44
import { source } from "@/lib/source";
5+
import { Footer } from "@/components/layout/footer";
56

67
const layoutOptions: DocsLayoutProps = {
78
...baseOptions,
@@ -23,5 +24,10 @@ const layoutOptions: DocsLayoutProps = {
2324
};
2425

2526
export default function Layout({ children }: { children: ReactNode }) {
26-
return <DocsLayout {...layoutOptions}>{children}</DocsLayout>;
27+
return (
28+
<>
29+
<DocsLayout {...layoutOptions}>{children}</DocsLayout>
30+
<Footer />
31+
</>
32+
);
2733
}

docs/src/app/layout.config.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,5 @@ export const baseOptions: BaseLayoutProps = {
1010
text: "documentation",
1111
url: "/docs",
1212
},
13-
{
14-
text: "privacy",
15-
url: "/privacy",
16-
},
1713
],
1814
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Link from "next/link";
2+
3+
export function Footer() {
4+
return (
5+
<footer className="border-t bg-card/50 py-12">
6+
<div className="container flex flex-col items-center justify-center gap-4 text-center">
7+
<div className="flex flex-col sm:flex-row items-center justify-center gap-2 text-sm text-muted-foreground">
8+
<div className="flex items-center gap-4">
9+
<Link
10+
href="/privacy"
11+
className="hover:text-foreground transition-colors"
12+
>
13+
Privacy Policy
14+
</Link>
15+
<Link
16+
href="/terms"
17+
className="hover:text-foreground transition-colors"
18+
>
19+
Terms of Service
20+
</Link>
21+
</div>
22+
<span className="hidden sm:inline"></span>
23+
<span>Built with ❤️ for developers</span>
24+
</div>
25+
<div className="text-xs text-muted-foreground">
26+
© 2025 funnel. Open source tunneling solution.
27+
</div>
28+
</div>
29+
</footer>
30+
);
31+
}

docs/src/components/legal/cookie-banner.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,25 @@ export function CookieBanner() {
1111

1212
useEffect(() => {
1313
const hasConsent = localStorage.getItem(CONSENT_KEY);
14-
if (!hasConsent) {
14+
15+
if (hasConsent !== "accepted") {
1516
setIsVisible(true);
1617
}
1718
}, []);
1819

1920
const handleAccept = () => {
2021
localStorage.setItem(CONSENT_KEY, "accepted");
2122
setIsVisible(false);
23+
24+
if (
25+
typeof window !== "undefined" &&
26+
(window as unknown as { posthog?: any }).posthog
27+
) {
28+
(window as unknown as { posthog?: any }).posthog.opt_in_capturing();
29+
}
2230
};
2331

2432
const handleDecline = () => {
25-
localStorage.setItem(CONSENT_KEY, "declined");
2633
setIsVisible(false);
2734

2835
if (
@@ -49,7 +56,7 @@ export function CookieBanner() {
4956
<Link href="/privacy" className="underline hover:no-underline">
5057
privacy policy
5158
</Link>{" "}
52-
for details.
59+
for details. If you decline, we won't store anything at all.
5360
</p>
5461
</div>
5562

docs/src/components/legal/privacy-aware-analytics.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function PrivacyAwareAnalytics() {
1515
if (posthog) {
1616
if (consentGiven) {
1717
posthog.opt_in_capturing();
18-
} else if (consent === "declined") {
18+
} else {
1919
posthog.opt_out_capturing();
2020
}
2121
}

0 commit comments

Comments
 (0)