From 97ea3982a90c232afb2cd1d46e7a5bc6e7b07a5d Mon Sep 17 00:00:00 2001 From: "wizard-ci-bot[bot]" <254716194+wizard-ci-bot[bot]@users.noreply.github.com> Date: Wed, 28 Oct 2026 16:59:04 +0000 Subject: [PATCH] wizard-ci: react-router/rrv7-starter --- .../react-router/rrv7-starter/.env.example | 2 + .../rrv7-starter/app/components/PostCard.tsx | 9 ++ .../app/lib/posthog-logs.client.ts | 14 +++ .../rrv7-starter/app/lib/posthog.client.ts | 38 ++++++ .../react-router/rrv7-starter/app/root.tsx | 5 + .../rrv7-starter/app/routes/buy-followers.tsx | 34 ++++- .../rrv7-starter/app/routes/profile.tsx | 10 +- .../react-router/rrv7-starter/env.d.ts | 2 + .../react-router/rrv7-starter/package.json | 1 + .../react-router/rrv7-starter/pnpm-lock.yaml | 116 ++++++++++++++++++ 10 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 apps/basic-integration/react-router/rrv7-starter/app/lib/posthog-logs.client.ts create mode 100644 apps/basic-integration/react-router/rrv7-starter/app/lib/posthog.client.ts diff --git a/apps/basic-integration/react-router/rrv7-starter/.env.example b/apps/basic-integration/react-router/rrv7-starter/.env.example index f7c4b66e1..71e5348e5 100644 --- a/apps/basic-integration/react-router/rrv7-starter/.env.example +++ b/apps/basic-integration/react-router/rrv7-starter/.env.example @@ -1 +1,3 @@ VITE_SITE_URL=http://localhost:3000 +VITE_POSTHOG_PROJECT_TOKEN= +VITE_POSTHOG_HOST= diff --git a/apps/basic-integration/react-router/rrv7-starter/app/components/PostCard.tsx b/apps/basic-integration/react-router/rrv7-starter/app/components/PostCard.tsx index 0d50b97d4..dd808ac05 100644 --- a/apps/basic-integration/react-router/rrv7-starter/app/components/PostCard.tsx +++ b/apps/basic-integration/react-router/rrv7-starter/app/components/PostCard.tsx @@ -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 ( diff --git a/apps/basic-integration/react-router/rrv7-starter/app/lib/posthog-logs.client.ts b/apps/basic-integration/react-router/rrv7-starter/app/lib/posthog-logs.client.ts new file mode 100644 index 000000000..d99ab4448 --- /dev/null +++ b/apps/basic-integration/react-router/rrv7-starter/app/lib/posthog-logs.client.ts @@ -0,0 +1,14 @@ +import posthog, { isPostHogConfigured } from './posthog.client' + +type LogAttributes = Record + +export const posthogLogger = { + info: (message: string, attributes: LogAttributes) => { + if (isPostHogConfigured) { + posthog.logger.info(message, attributes) + } + }, +} + +export { isPostHogConfigured } +export default posthog diff --git a/apps/basic-integration/react-router/rrv7-starter/app/lib/posthog.client.ts b/apps/basic-integration/react-router/rrv7-starter/app/lib/posthog.client.ts new file mode 100644 index 000000000..623682a34 --- /dev/null +++ b/apps/basic-integration/react-router/rrv7-starter/app/lib/posthog.client.ts @@ -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 diff --git a/apps/basic-integration/react-router/rrv7-starter/app/root.tsx b/apps/basic-integration/react-router/rrv7-starter/app/root.tsx index 368952387..de7b2ff55 100644 --- a/apps/basic-integration/react-router/rrv7-starter/app/root.tsx +++ b/apps/basic-integration/react-router/rrv7-starter/app/root.tsx @@ -1,3 +1,4 @@ +import { useEffect } from 'react' import { isRouteErrorResponse, Links, @@ -88,6 +89,10 @@ export default function App() { const location = useLocation() + useEffect(() => { + void import('@/lib/posthog.client') + }, []) + return ( (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) @@ -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) @@ -75,7 +107,7 @@ export default function BuyFollowers() { return (
setSelectedPackage(index)} + onClick={() => handlePackageSelection(index)} className={cn( 'bg-primary/5 border-2 rounded-lg p-6 cursor-pointer transition', isSelected diff --git a/apps/basic-integration/react-router/rrv7-starter/app/routes/profile.tsx b/apps/basic-integration/react-router/rrv7-starter/app/routes/profile.tsx index 50f566c7a..b5f039f49 100644 --- a/apps/basic-integration/react-router/rrv7-starter/app/routes/profile.tsx +++ b/apps/basic-integration/react-router/rrv7-starter/app/routes/profile.tsx @@ -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' }) + } + }) } } @@ -142,7 +149,6 @@ export default function Profile() { Followed you 2 minutes ago
{ const newFollowing = getFollowing() + 1 setFollowing(newFollowing) diff --git a/apps/basic-integration/react-router/rrv7-starter/env.d.ts b/apps/basic-integration/react-router/rrv7-starter/env.d.ts index fb6c3c984..a56fa8a53 100644 --- a/apps/basic-integration/react-router/rrv7-starter/env.d.ts +++ b/apps/basic-integration/react-router/rrv7-starter/env.d.ts @@ -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 { diff --git a/apps/basic-integration/react-router/rrv7-starter/package.json b/apps/basic-integration/react-router/rrv7-starter/package.json index e086c33f4..a45e5a9ef 100644 --- a/apps/basic-integration/react-router/rrv7-starter/package.json +++ b/apps/basic-integration/react-router/rrv7-starter/package.json @@ -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", diff --git a/apps/basic-integration/react-router/rrv7-starter/pnpm-lock.yaml b/apps/basic-integration/react-router/rrv7-starter/pnpm-lock.yaml index 3df1a93a5..66c7b94b3 100644 --- a/apps/basic-integration/react-router/rrv7-starter/pnpm-lock.yaml +++ b/apps/basic-integration/react-router/rrv7-starter/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: isbot: specifier: ^5.1.17 version: 5.1.32 + posthog-js: + specifier: ^1.441.2 + version: 1.441.2(@types/react@19.2.7)(react@19.2.3) react: specifier: ^19.0.0 version: 19.2.3 @@ -544,6 +547,15 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@posthog/browser-common@0.10.1': + resolution: {integrity: sha512-gKtBGEsjxNExO/19trnkiXTHFX0075vXn69zZ+lPlXy6P/DkED4644WqjDN/GIWr1Y5en2dcVJPOqUmVO+drkg==} + + '@posthog/core@1.61.1': + resolution: {integrity: sha512-qyMTxPfjeJkHIhpcukOgBN3BWXbCyFRPz8/Voy5qZtVh9NZqj3EhC6LLeYZuJhL3WpqhQTgn2FMIwAo/ag6fmw==} + + '@posthog/types@1.418.0': + resolution: {integrity: sha512-WqDXUWH1R8OilBp2PfDpQIRZSCs3QyOnw7H3YK7lvZLCMIsOqSZAKJrrqYWt4f7FvnVCACRuNGCC0HKh3J/HWw==} + '@react-router/dev@7.11.0': resolution: {integrity: sha512-g1ou5Zw3r4mCU0L+EXH4vRtAiyt8qz1JOvL1k+PW4rZ4+71h5nBy/fLgD7cg5BnzQZmjRO1PzCgpF5BIrlKYxQ==} engines: {node: '>=20.0.0'} @@ -637,66 +649,79 @@ packages: resolution: {integrity: sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.55.1': resolution: {integrity: sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.55.1': resolution: {integrity: sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.55.1': resolution: {integrity: sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.55.1': resolution: {integrity: sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.55.1': resolution: {integrity: sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.55.1': resolution: {integrity: sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.55.1': resolution: {integrity: sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.55.1': resolution: {integrity: sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.55.1': resolution: {integrity: sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.55.1': resolution: {integrity: sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.55.1': resolution: {integrity: sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.55.1': resolution: {integrity: sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.55.1': resolution: {integrity: sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==} @@ -790,6 +815,9 @@ packages: '@types/serve-static@2.2.0': resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@typescript-eslint/eslint-plugin@8.52.0': resolution: {integrity: sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1164,6 +1192,9 @@ packages: resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} + core-js@3.51.0: + resolution: {integrity: sha512-7bDKx/5jm5MxzsXxc93g6Z2+4ZsuT/MddrfRmTDJNAkWsYWHU8EVNEsBiIEWnMAMCHMmRfUEjkuo3jeNBOIHRw==} + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -1264,6 +1295,9 @@ packages: dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dompurify@3.4.17: + resolution: {integrity: sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w==} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -1585,6 +1619,9 @@ packages: picomatch: optional: true + fflate@0.4.9: + resolution: {integrity: sha512-zdxgIEddhfsyCaWpJ2SdXEP8ZMrKJ6+5jl4OupODcywU0IhRk6gdXuVGcPICyfx2H97hVK7xmJtRLPjkxAX8Vw==} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -2309,6 +2346,25 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + posthog-js@1.441.2: + resolution: {integrity: sha512-PsELSUSVCx80BfbtMtir8fW6scxVj+2CvsG+Vj2j9eTQYQL1AzsaZr73pqJk1XWEcSt+B1hEfirz3iFVQGVQkQ==} + peerDependencies: + '@types/react': '>=16.8.0' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + preact@10.29.8: + resolution: {integrity: sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==} + peerDependencies: + preact-render-to-string: '>=5' + peerDependenciesMeta: + preact-render-to-string: + optional: true + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2341,6 +2397,9 @@ packages: resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} engines: {node: '>=0.6'} + query-selector-shadow-dom@1.0.1: + resolution: {integrity: sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -2839,6 +2898,12 @@ packages: terser: optional: true + web-vitals@6.2.1: + resolution: {integrity: sha512-rLcLXA2sx6+9dE88NHFubwTtGxpK4yYBLj6qHPdFoCaLr0cXGb4efOqtKLlm4loGA4OEKHIQKMKzZkKyOh5ctw==} + + web-vitals@6.2.3: + resolution: {integrity: sha512-Dmy+vdO1UPMqXiAtZSNayhl4f794Bxfd94W4HIj2HlYtczEQfEOon969memlcpcHrTuOKLa5baFjX7WbgmOq+A==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -3313,6 +3378,20 @@ snapshots: '@pkgr/core@0.2.9': {} + '@posthog/browser-common@0.10.1': + dependencies: + '@posthog/core': 1.61.1 + '@posthog/types': 1.418.0 + preact: 10.29.8 + transitivePeerDependencies: + - preact-render-to-string + + '@posthog/core@1.61.1': + dependencies: + '@posthog/types': 1.418.0 + + '@posthog/types@1.418.0': {} + '@react-router/dev@7.11.0(@react-router/serve@7.11.0(react-router@7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3))(@types/node@20.19.27)(react-router@7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@5.4.21(@types/node@20.19.27))': dependencies: '@babel/core': 7.28.5 @@ -3542,6 +3621,9 @@ snapshots: '@types/http-errors': 2.0.5 '@types/node': 20.19.27 + '@types/trusted-types@2.0.7': + optional: true + '@typescript-eslint/eslint-plugin@8.52.0(@typescript-eslint/parser@8.52.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -4023,6 +4105,8 @@ snapshots: cookie@1.1.1: {} + core-js@3.51.0: {} + create-require@1.1.1: {} cross-env@7.0.3: @@ -4104,6 +4188,10 @@ snapshots: '@babel/runtime': 7.28.4 csstype: 3.2.3 + dompurify@3.4.17: + optionalDependencies: + '@types/trusted-types': 2.0.7 + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -4533,6 +4621,8 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fflate@0.4.9: {} + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -5205,6 +5295,26 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + posthog-js@1.441.2(@types/react@19.2.7)(react@19.2.3): + dependencies: + '@posthog/browser-common': 0.10.1 + '@posthog/core': 1.61.1 + '@posthog/types': 1.418.0 + core-js: 3.51.0 + dompurify: 3.4.17 + fflate: 0.4.9 + preact: 10.29.8 + query-selector-shadow-dom: 1.0.1 + web-vitals: 6.2.3 + web-vitals-soft-navs: web-vitals@6.2.1 + optionalDependencies: + '@types/react': 19.2.7 + react: 19.2.3 + transitivePeerDependencies: + - preact-render-to-string + + preact@10.29.8: {} + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.1: @@ -5234,6 +5344,8 @@ snapshots: dependencies: side-channel: 1.1.0 + query-selector-shadow-dom@1.0.1: {} + queue-microtask@1.2.3: {} range-parser@1.2.1: {} @@ -5836,6 +5948,10 @@ snapshots: '@types/node': 20.19.27 fsevents: 2.3.3 + web-vitals@6.2.1: {} + + web-vitals@6.2.3: {} + webidl-conversions@3.0.1: {} whatwg-url@5.0.0: