Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions apps/www/components/posthog-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,40 @@ import { usePathname, useSearchParams } from "next/navigation"
import posthog from "posthog-js"
import { PostHogProvider } from "posthog-js/react"

if (typeof window !== "undefined") {
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_API_KEY!, {
api_host: "https://app.posthog.com",
capture_pageview: true,
session_recording: {
maskAllInputs: false,
},
// Enable debug mode in development
loaded: (posthog) => {
if (process.env.NODE_ENV === "development") posthog.debug()
},
})
}
import {
capturePostHogEvent,
initPostHog,
isPostHogEnabled,
} from "@/lib/posthog"

initPostHog()

export function PostHogPageview(): React.ReactNode {
const pathname = usePathname()
const searchParams = useSearchParams()

useEffect(() => {
if (pathname) {
let url = window.origin + pathname
if (searchParams && searchParams.toString()) {
url = url + `?${searchParams.toString()}`
}
posthog.capture("$pageview", {
$current_url: url,
})
if (!isPostHogEnabled || !pathname) {
return
}

let url = window.origin + pathname
if (searchParams && searchParams.toString()) {
url = url + `?${searchParams.toString()}`
}

capturePostHogEvent("$pageview", {
$current_url: url,
})
}, [pathname, searchParams])

return <></>
}

export function PHProvider({ children }: { children: React.ReactNode }) {
if (!isPostHogEnabled) {
return children
}

return <PostHogProvider client={posthog}>{children}</PostHogProvider>
}
4 changes: 2 additions & 2 deletions apps/www/components/sidebar-cta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import Link from "next/link"
import { CheckIcon, ChevronRight } from "lucide-react"
import posthog from "posthog-js"

import { trackEvent } from "@/lib/events"
import { Button } from "@/components/ui/button"
Expand Down Expand Up @@ -116,7 +115,8 @@ export function ProductHuntCTA() {
<Link
href="https://www.producthunt.com/posts/magic-ui-2?utm_source=sidebar-cta&utm_medium=sidebar-cta&utm_campaign=product-hunt-sidebar-cta"
target="_blank"
onClick={() => posthog.capture("product_hunt_sidebar_cta_clicked")}
rel="noopener noreferrer"
onClick={() => trackEvent({ name: "product_hunt_sidebar_cta_clicked" })}
className="group my-20 flex w-full flex-col items-center justify-center gap-2 rounded-xl bg-[#ff6154] p-4 text-center text-lg leading-tight font-medium text-white"
>
<TextAnimate animate="blurInUp" by="word" className="text-2xl">
Expand Down
9 changes: 6 additions & 3 deletions apps/www/components/site-banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@

import Link from "next/link"
import { ChevronRight } from "lucide-react"
import posthog from "posthog-js"

import { trackEvent } from "@/lib/events"

export function ProBanner() {
return (
<div className="group relative top-0 bg-indigo-600 py-3 text-white transition-all duration-300 md:py-0">
<div className="container flex flex-col items-center justify-center gap-4 md:h-12 md:flex-row">
<Link
href="https://pro.magicui.design"
onClick={() => posthog.capture("banner_cta_clicked")}
onClick={() => trackEvent({ name: "banner_cta_clicked" })}
target="_blank"
rel="noopener noreferrer"
className="inline-flex text-xs leading-normal md:text-sm"
>
✨{" "}
Expand All @@ -34,8 +36,9 @@ export function ProductHuntBanner() {
<div className="container flex flex-col items-center justify-center gap-4 md:h-12 md:flex-row">
<Link
href="https://www.producthunt.com/posts/magic-ui-2?utm_source=site-banner&utm_medium=banner&utm_campaign=product-hunt-banner"
onClick={() => posthog.capture("product_hunt_banner_clicked")}
onClick={() => trackEvent({ name: "product_hunt_banner_clicked" })}
target="_blank"
rel="noopener noreferrer"
className="inline-flex text-xs leading-normal md:text-sm"
>
✨{" "}
Expand Down
8 changes: 6 additions & 2 deletions apps/www/lib/events.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import posthog from "posthog-js"
import { z } from "zod"

import { capturePostHogEvent } from "@/lib/posthog"

const eventSchema = z.object({
name: z.enum([
"copy_npm_command",
Expand All @@ -19,6 +20,9 @@ const eventSchema = z.object({

"sidebar_cta_clicked",
"header_cta_clicked",
"banner_cta_clicked",
"product_hunt_banner_clicked",
"product_hunt_sidebar_cta_clicked",
]),
properties: z
.record(
Expand All @@ -33,6 +37,6 @@ export type Event = z.infer<typeof eventSchema>
export function trackEvent(input: Event): void {
const event = eventSchema.parse(input)
if (event) {
posthog.capture(event.name, event.properties)
capturePostHogEvent(event.name, event.properties)
}
}
48 changes: 48 additions & 0 deletions apps/www/lib/posthog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import posthog from "posthog-js"

type PostHogPropertyValue = string | number | boolean | null

export type PostHogEventProperties = Record<string, PostHogPropertyValue>

const posthogApiKey = process.env.NEXT_PUBLIC_POSTHOG_API_KEY?.trim() ?? ""

export const isPostHogEnabled = posthogApiKey.length > 0

let hasInitializedPostHog = false

export function initPostHog(): void {
if (
typeof window === "undefined" ||
!isPostHogEnabled ||
hasInitializedPostHog
) {
return
}

hasInitializedPostHog = true

posthog.init(posthogApiKey, {
api_host: "https://app.posthog.com",
capture_pageview: true,
session_recording: {
maskAllInputs: false,
},
loaded: (client) => {
if (process.env.NODE_ENV === "development") {
client.debug()
}
},
})
}

export function capturePostHogEvent(
name: string,
properties?: PostHogEventProperties
): void {
if (!isPostHogEnabled) {
return
}

initPostHog()
posthog.capture(name, properties)
}
Loading