Skip to content

Commit 576ecce

Browse files
authored
feat(analytics): add OpenPanel analytics and sponsorship (#28)
- Add OpenPanel as Open Source Program sponsor with logo - Replace Umami with OpenPanel analytics tracking - Add analytics attribution in footer and README Co-authored-by: Justin Levine <20596508+justinlevinedotme@users.noreply.github.com>
1 parent 61cf79f commit 576ecce

8 files changed

Lines changed: 166 additions & 12 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ pnpm registry:build # registry only
4848

4949
See [CONTRIBUTING.md](./CONTRIBUTING.md).
5050

51+
## Sponsors
52+
53+
Analytics by [OpenPanel](https://openpanel.dev/open-source?utm_source=justinlevine.me).
54+
5155
## License
5256

5357
[MIT](./LICENSE)

apps/docs/app/layout.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export const metadata: Metadata = {
7272
},
7373
}
7474

75-
import Script from "next/script"
75+
import { Analytics } from "@/components/analytics"
7676

7777
export default function RootLayout({
7878
children,
@@ -118,12 +118,7 @@ export default function RootLayout({
118118
>
119119
<head />
120120
<body className="antialiased">
121-
<Script
122-
id="umami-analytics"
123-
src="https://cloud.umami.is/script.js"
124-
data-website-id="1577ed14-ed62-48d4-a679-1e96a0f4ae54"
125-
strategy="afterInteractive"
126-
/>
121+
<Analytics />
127122
<script
128123
type="application/ld+json"
129124
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}

apps/docs/app/sponsor/page.tsx

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Metadata } from "next"
22
import Image from "next/image"
33
import Link from "next/link"
44
import { Heart, ExternalLink, Star, Plus } from "lucide-react"
5+
import type { ReactNode } from "react"
56
import { JalcoLogo } from "@/components/icons/jalco-logo"
67
import { ThemeSwitcher } from "@/components/docs/theme-switcher"
78
import { GitHubStarsButton } from "@/registry/github-stars-button/github-stars-button"
@@ -46,11 +47,57 @@ async function getStargazers(): Promise<Stargazer[]> {
4647
return pages.filter((s) => s.login !== "jal-co")
4748
}
4849

49-
const tiers = [
50+
function OpenPanelLogo({ className }: { className?: string }) {
51+
return (
52+
<svg viewBox="55 28 210 42" fill="currentColor" aria-hidden="true" className={className}>
53+
<path d="M104.374 36.542a5.173 5.173 0 1 0-10.347 0V60.42a5.174 5.174 0 1 0 10.347 0zM120.293 36.542a5.174 5.174 0 1 0-10.347 0v7.163a5.173 5.173 0 1 0 10.347 0z"></path>
54+
<path d="M74.212 31C66.362 31 60 37.363 60 45.212v5.808c0 7.85 6.363 14.212 14.212 14.212 7.85 0 14.212-6.363 14.212-14.212v-5.808c0-7.85-6.363-14.212-14.212-14.212m.026 8.36a5.174 5.174 0 0 0-5.174 5.174v7.163a5.174 5.174 0 1 0 10.348 0v-7.163a5.174 5.174 0 0 0-5.174-5.174" fillRule="evenodd" clipRule="evenodd"></path>
55+
<path d="M146 57.384q-2.472 0-4.248-1.056-1.776-1.08-2.736-3.072t-.96-4.752.96-4.752q.96-2.016 2.736-3.096t4.248-1.08q2.496 0 4.272 1.08 1.8 1.08 2.736 3.096.96 1.992.96 4.752t-.96 4.752q-.936 1.992-2.736 3.072-1.776 1.056-4.272 1.056m0-2.376q1.656 0 2.832-.768 1.2-.768 1.824-2.208.624-1.464.624-3.528t-.624-3.528-1.824-2.232q-1.176-.792-2.832-.792-1.632 0-2.808.792-1.176.768-1.824 2.232-.624 1.464-.624 3.528t.624 3.528q.648 1.44 1.824 2.208t2.808.768m10.823 5.592V44.232h2.4l.072 2.736-.288-.144q.48-1.416 1.584-2.136 1.104-.744 2.544-.744 1.872 0 3.072.936 1.224.912 1.8 2.424.6 1.512.6 3.312t-.6 3.312q-.576 1.512-1.8 2.448-1.2.912-3.072.912-.96 0-1.8-.336a4.2 4.2 0 0 1-1.44-.936 3.6 3.6 0 0 1-.816-1.464l.288-.288V60.6zm5.856-5.52q1.536 0 2.4-1.176.888-1.176.888-3.288t-.888-3.288q-.864-1.176-2.4-1.176-1.008 0-1.752.504-.744.48-1.152 1.488t-.408 2.472.384 2.472q.408 1.008 1.152 1.512.768.48 1.776.48m13.768 2.208q-1.872 0-3.24-.816-1.344-.816-2.088-2.328-.72-1.512-.72-3.528t.72-3.504q.744-1.512 2.088-2.328 1.344-.84 3.168-.84 1.728 0 3.048.816 1.32.792 2.04 2.304.744 1.512.744 3.648v.648h-9.168q.096 1.872.984 2.808.912.936 2.448.936 1.128 0 1.872-.528t1.032-1.416l2.64.168a5.3 5.3 0 0 1-1.992 2.88q-1.464 1.08-3.576 1.08m-3.408-7.848h6.48q-.12-1.704-.984-2.52-.84-.816-2.16-.816-1.368 0-2.256.864-.864.84-1.08 2.472M184.784 57V44.232h2.328l.096 3.408-.312-.168q.216-1.248.816-2.016t1.464-1.128a4.6 4.6 0 0 1 1.872-.384q1.44 0 2.376.648.96.624 1.44 1.728.504 1.08.504 2.472V57h-2.544v-7.44q0-1.128-.24-1.896t-.792-1.176-1.44-.408q-1.344 0-2.184.888t-.84 2.592V57zm14.21 0V39.96h6.36q2.928 0 4.56 1.416 1.632 1.392 1.632 3.888 0 1.656-.744 2.88-.744 1.2-2.136 1.848-1.368.624-3.312.624h-3.768V57zm2.592-8.736h3.696q1.752 0 2.664-.744.912-.768.912-2.256 0-1.464-.912-2.184-.912-.744-2.664-.744h-3.696zm15.954 9.024q-1.992 0-3.192-.912-1.176-.912-1.176-2.568t.984-2.568q1.008-.936 3.096-1.344l4.392-.84q0-1.488-.696-2.208-.696-.744-2.064-.744-1.224 0-1.92.552-.696.528-.96 1.584l-2.616-.168q.36-1.92 1.776-3.024 1.44-1.104 3.72-1.104 2.592 0 3.936 1.392 1.368 1.368 1.368 3.864v4.968q0 .456.144.648.168.168.528.168h.456V57q-.12.024-.384.048t-.552.024q-.816 0-1.416-.264a1.75 1.75 0 0 1-.864-.864q-.288-.624-.288-1.656l.264.12a3.03 3.03 0 0 1-.84 1.488q-.624.648-1.608 1.032a5.9 5.9 0 0 1-2.088.36m.408-2.016q1.152 0 1.968-.432.816-.456 1.272-1.248t.456-1.8v-.816l-3.744.72q-1.152.216-1.632.696-.456.456-.456 1.176 0 .816.552 1.272.576.432 1.584.432M227.464 57V44.232h2.328l.096 3.408-.312-.168q.216-1.248.816-2.016t1.464-1.128a4.6 4.6 0 0 1 1.872-.384q1.44 0 2.376.648.96.624 1.44 1.728.504 1.08.504 2.472V57h-2.544v-7.44q0-1.128-.24-1.896t-.792-1.176-1.44-.408q-1.344 0-2.184.888t-.84 2.592V57zm19.154.288q-1.87 0-3.239-.816-1.344-.816-2.088-2.328-.72-1.512-.72-3.528t.72-3.504q.744-1.512 2.088-2.328 1.344-.84 3.168-.84 1.728 0 3.048.816 1.32.792 2.04 2.304.744 1.512.744 3.648v.648h-9.168q.096 1.872.984 2.808.912.936 2.448.936 1.128 0 1.872-.528t1.032-1.416l2.64.168a5.3 5.3 0 0 1-1.992 2.88q-1.464 1.08-3.577 1.08m-3.407-7.848h6.48q-.12-1.704-.984-2.52-.84-.816-2.16-.816-1.368 0-2.256.864-.864.84-1.08 2.472M257.857 57q-1.248 0-2.016-.648t-.768-2.064V39.96h2.544v14.088q0 .432.216.648.24.216.672.216h1.008V57z"></path>
56+
</svg>
57+
)
58+
}
59+
60+
interface Sponsor {
61+
name: string
62+
href: string
63+
logo?: string
64+
logoComponent?: ReactNode
65+
}
66+
67+
const tiers: {
68+
name: string
69+
slots: number
70+
sponsors: Sponsor[]
71+
colors: {
72+
bg: string
73+
text: string
74+
border: string
75+
slotBg: string
76+
slotBorder: string
77+
}
78+
}[] = [
79+
{
80+
name: "Open Source Program",
81+
slots: 4,
82+
sponsors: [
83+
{
84+
name: "OpenPanel",
85+
href: "https://openpanel.dev/open-source?utm_source=justinlevine.me",
86+
logoComponent: <OpenPanelLogo className="h-8 w-auto" />,
87+
},
88+
],
89+
colors: {
90+
bg: "linear-gradient(145deg, #22c55e 0%, #4ade80 30%, #16a34a 60%, #86efac 100%)",
91+
text: "#052e16",
92+
border: "#16a34a",
93+
slotBg: "rgba(34, 197, 94, 0.06)",
94+
slotBorder: "rgba(22, 163, 74, 0.2)",
95+
},
96+
},
5097
{
5198
name: "Gold",
5299
slots: 3,
53-
sponsors: [] as { name: string; href: string; logo?: string }[],
100+
sponsors: [],
54101
colors: {
55102
bg: "linear-gradient(145deg, #d4a84b 0%, #f5d98a 30%, #c9952e 60%, #e8c55a 100%)",
56103
text: "#5c3d0e",
@@ -62,7 +109,7 @@ const tiers = [
62109
{
63110
name: "Silver",
64111
slots: 3,
65-
sponsors: [] as { name: string; href: string; logo?: string }[],
112+
sponsors: [],
66113
colors: {
67114
bg: "linear-gradient(145deg, #a8a8a8 0%, #d4d4d4 30%, #8a8a8a 60%, #c0c0c0 100%)",
68115
text: "#2a2a2a",
@@ -74,7 +121,7 @@ const tiers = [
74121
{
75122
name: "Bronze",
76123
slots: 4,
77-
sponsors: [] as { name: string; href: string; logo?: string }[],
124+
sponsors: [],
78125
colors: {
79126
bg: "linear-gradient(145deg, #b5745a 0%, #d4956e 30%, #8c5a3e 60%, #c98a68 100%)",
80127
text: "#3d1e0e",
@@ -248,7 +295,11 @@ export default async function SponsorPage() {
248295
borderColor: tier.colors.slotBorder,
249296
}}
250297
>
251-
{sponsor.logo ? (
298+
{sponsor.logoComponent ? (
299+
<span className="opacity-60 transition-opacity group-hover:opacity-100">
300+
{sponsor.logoComponent}
301+
</span>
302+
) : sponsor.logo ? (
252303
<Image
253304
src={sponsor.logo}
254305
alt={sponsor.name}

apps/docs/components/analytics.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use client"
2+
3+
import { useEffect } from "react"
4+
import { op } from "@/lib/openpanel"
5+
6+
export function Analytics() {
7+
useEffect(() => {
8+
// OpenPanel auto-tracks screen views, outgoing links, and data-track attributes
9+
// Accessing op ensures the client is initialized on mount
10+
void op
11+
}, [])
12+
13+
return null
14+
}

apps/docs/components/docs/footer.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ export function SiteFooter() {
2828
Open source React components for Tailwind CSS. Free forever, never
2929
paywalled.
3030
</p>
31+
<p className="text-xs text-muted-foreground">
32+
Analytics by{" "}
33+
<a
34+
href="https://openpanel.dev/open-source?utm_source=justinlevine.me"
35+
target="_blank"
36+
rel="noopener noreferrer"
37+
className="underline underline-offset-2 hover:text-foreground"
38+
>
39+
OpenPanel
40+
</a>
41+
</p>
3142
</div>
3243

3344
<div className="flex gap-10 text-sm">

apps/docs/lib/openpanel.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { OpenPanel } from "@openpanel/web"
2+
3+
export const op = new OpenPanel({
4+
clientId: process.env.NEXT_PUBLIC_OPENPANEL_CLIENT_ID ?? "",
5+
trackScreenViews: true,
6+
trackOutgoingLinks: true,
7+
trackAttributes: true,
8+
})

apps/docs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
},
1616
"dependencies": {
1717
"@chenglou/pretext": "^0.0.4",
18+
"@openpanel/web": "^1.4.0",
1819
"@orama/orama": "^3.1.18",
1920
"@radix-ui/react-label": "^2.1.7",
2021
"@radix-ui/react-slot": "^1.2.3",

pnpm-lock.yaml

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)