Skip to content
Closed
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
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
VITE_SITE_URL=http://localhost:3000
VITE_POSTHOG_PROJECT_TOKEN=
VITE_POSTHOG_HOST=
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ export function PostCard({ post }: PostCardProps) {
const newLikedState = toggleLikedPost(post.id)
setLiked(newLikedState)
setLikes((prev) => (prev + (newLikedState ? 1 : -1)))

if (newLikedState) {
void import('@/lib/posthog-logs.client').then(({ default: posthog, isPostHogConfigured, posthogLogger }) => {
if (isPostHogConfigured) {
posthog.capture('post_liked')
posthogLogger.info('post liked', { event: 'post_liked' })
}
})
}
}

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import posthog, { isPostHogConfigured } from './posthog.client'

type LogAttributes = Record<string, string | number | boolean>

export const posthogLogger = {
info: (message: string, attributes: LogAttributes) => {
if (isPostHogConfigured) {
posthog.logger.info(message, attributes)
}
},
}

export { isPostHogConfigured }
export default posthog
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import posthog from 'posthog-js'

const posthogProjectToken = import.meta.env.VITE_POSTHOG_PROJECT_TOKEN
const posthogHost = import.meta.env.VITE_POSTHOG_HOST
const missingVariables = [
['VITE_POSTHOG_PROJECT_TOKEN', posthogProjectToken],
['VITE_POSTHOG_HOST', posthogHost],
].filter(([, value]) => !value)
export const isPostHogConfigured = missingVariables.length === 0

if (!posthogProjectToken || !posthogHost) {
if (import.meta.env.DEV) {
throw new Error(
missingVariables
.map(
([name]) =>
`${name} variable required by PostHog is missing or un-configured, this causes events to be silently missed. This error stops appearing once ${name} is configured`
)
.join('\n')
)
}
} else {
posthog.init(posthogProjectToken, {
api_host: posthogHost,
defaults: '2026-01-30',
logs: {
serviceName: 'clouthub-web',
environment: import.meta.env.MODE,
},
capture_exceptions: {
capture_unhandled_errors: true,
capture_unhandled_rejections: true,
capture_console_errors: false,
},
})
}

export default posthog
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useEffect } from 'react'
import {
isRouteErrorResponse,
Links,
Expand Down Expand Up @@ -88,6 +89,10 @@ export default function App() {

const location = useLocation()

useEffect(() => {
void import('@/lib/posthog.client')
}, [])

return (
<RouteTransitionManager
appear
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@ export default function BuyFollowers() {
const [selectedPackage, setSelectedPackage] = useState<number | null>(null)
const [purchased, setPurchased] = useState(false)

const handlePackageSelection = (packageIndex: number) => {
const pkg = followerPackages[packageIndex]
setSelectedPackage(packageIndex)

void import('@/lib/posthog.client').then(({ default: posthog, isPostHogConfigured }) => {
if (isPostHogConfigured) {
posthog.capture('follower_package_selected', {
follower_amount: pkg.amount,
bonus_amount: pkg.bonus,
price: pkg.price,
})
}
})
}

const handlePurchase = () => {
if (selectedPackage === null) return
setPurchased(true)
Expand All @@ -34,6 +49,23 @@ export default function BuyFollowers() {
// Save to localStorage
addFollowers(totalFollowers)
addPurchasedFollowers(totalFollowers)

void import('@/lib/posthog-logs.client').then(({ default: posthog, isPostHogConfigured, posthogLogger }) => {
if (isPostHogConfigured) {
const purchaseDetails = {
follower_amount: pkg.amount,
bonus_amount: pkg.bonus,
total_follower_amount: totalFollowers,
price: pkg.price,
}

posthog.capture('follower_purchase_completed', purchaseDetails)
posthogLogger.info('follower purchase completed', {
event: 'follower_purchase_completed',
...purchaseDetails,
})
}
})

alert(`Purchase complete! You now have ${totalFollowers.toLocaleString()} more fake followers! (Saved to localStorage)`)
setPurchased(false)
Expand Down Expand Up @@ -75,7 +107,7 @@ export default function BuyFollowers() {
return (
<div
key={index}
onClick={() => setSelectedPackage(index)}
onClick={() => handlePackageSelection(index)}
className={cn(
'bg-primary/5 border-2 rounded-lg p-6 cursor-pointer transition',
isSelected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@ import { SITE_URL } from '@/lib/constants'
import { getFollowers, getFollowing, getPosts, setFollowing } from '@/lib/utils/localStorage'
import cn from '@/lib/utils/cn'

function FollowButton({ username, onFollow }: { username: string; onFollow: () => void }) {
function FollowButton({ onFollow }: { onFollow: () => void }) {
const [isFollowing, setIsFollowing] = useState(false)

const handleClick = () => {
setIsFollowing(!isFollowing)
if (!isFollowing) {
onFollow()

void import('@/lib/posthog-logs.client').then(({ default: posthog, isPostHogConfigured, posthogLogger }) => {
if (isPostHogConfigured) {
posthog.capture('profile_followed')
posthogLogger.info('profile followed', { event: 'profile_followed' })
}
})
}
}

Expand Down Expand Up @@ -142,7 +149,6 @@ export default function Profile() {
<span className="text-sm text-primary/50">Followed you 2 minutes ago</span>
</div>
<FollowButton
username={follower.username}
onFollow={() => {
const newFollowing = getFollowing() + 1
setFollowing(newFollowing)
Expand Down
2 changes: 2 additions & 0 deletions apps/basic-integration/react-router/rrv7-starter/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ declare const __vercel: {

interface ImportMetaEnv {
readonly VITE_SITE_URL: string | undefined
readonly VITE_POSTHOG_PROJECT_TOKEN: string | undefined
readonly VITE_POSTHOG_HOST: string | undefined
}

interface ImportMeta {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"clsx": "^2.1.1",
"gsap": "^3.12.7",
"isbot": "^5.1.17",
"posthog-js": "^1.441.2",
"react": "^19.0.0",
"react-device-detect": "^2.2.3",
"react-dom": "^19.0.0",
Expand Down
Loading
Loading