Files
stanza/apps/web/package.json
T
jake ab5ef7ec4a feat: add client-side PostHog analytics and refactor /api/events to use posthog-node
- Add `src/components/posthog-provider.tsx` — initializes the `posthog-js` browser SDK once (guarded by `VITE_PUBLIC_POSTHOG_KEY` and `posthog.__loaded`) with history-based pageview capture, pageleave tracking, and session replay + autocapture disabled; wraps the app shell in `__root.tsx` via `<PostHogProvider>`
- Add `src/lib/analytics.ts` with a `useAnalytics` hook that returns a stable `capture` callback bound to the PostHog singleton (no-ops when the key is absent or the SDK is uninitialized) and a `selectionProperties` helper that flattens slot/addon selections into a consistent event property shape across events
- Wire `capture` into `Builder` (`builder_module_selected`, `builder_module_deselected`, `builder_addon_toggled`) and `CommandPreview` (`builder_command_copied` with `package_manager`, `command`, `name_customized`, `module_count`, and per-slot properties); add an `onCopied` callback prop to `CopyButton` to fire the capture after a successful clipboard write
- Add `src/server/posthog.server.ts` — a lazy singleton that constructs a `posthog-node` `PostHog` client from `VITE_PUBLIC_POSTHOG_KEY`/`VITE_PUBLIC_POSTHOG_HOST` and returns `null` when unconfigured; refactor `/api/events` to use this client instead of a raw `fetch` to PostHog's `/batch/` endpoint, and flush via `waitUntil` from `@vercel/functions` so the serverless function stays alive past the response without blocking it
2026-05-21 21:32:20 -04:00

69 lines
2.0 KiB
JSON

{
"name": "@stanza/web",
"version": "0.1.0",
"private": true,
"license": "MIT",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"predev": "./scripts/prepare-registry.sh",
"prebuild": "./scripts/prepare-registry.sh",
"start": "node .output/server/index.mjs",
"check-types": "tsc --noEmit",
"test": "vitest run"
},
"dependencies": {
"@base-ui/react": "^1.5.0",
"@fontsource-variable/geist": "^5.2.9",
"@fontsource-variable/geist-mono": "^5.2.8",
"@pierre/trees": "1.0.0-beta.4",
"@stanza/registry": "workspace:*",
"@tabler/icons-react": "^3.44.0",
"@tailwindcss/vite": "^4.3.0",
"@tanstack/react-devtools": "^0.10.5",
"@tanstack/react-hotkeys": "^0.10.0",
"@tanstack/react-router": "^1.170.7",
"@tanstack/react-router-devtools": "^1.167.0",
"@tanstack/react-router-ssr-query": "^1.167.0",
"@tanstack/react-start": "^1.168.10",
"@tanstack/router-plugin": "^1.168.10",
"@vercel/analytics": "^2.0.1",
"@vercel/functions": "^3.6.0",
"@vercel/og": "^0.11.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"fumadocs-core": "^16.9.0",
"fumadocs-mdx": "^15.0.7",
"fumadocs-ui": "npm:@fumadocs/base-ui@^16.9.0",
"nitro": "^3.0.260429-beta",
"posthog-js": "^1.375.0",
"posthog-node": "^5.35.0",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react-resizable-panels": "^4.11.1",
"shadcn": "^4.8.0",
"shiki": "^4.1.0",
"sonner": "^2.0.7",
"tailwind-merge": "^3.6.0",
"tailwindcss": "^4.3.0",
"tw-animate-css": "^1.4.0",
"zod": "^4.4.3"
},
"devDependencies": {
"@tanstack/devtools-vite": "^0.7.0",
"@testing-library/dom": "^10.4.1",
"@testing-library/react": "^16.3.2",
"@types/mdx": "^2.0.13",
"@types/node": "^25.9.1",
"@types/react": "^19.2.15",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.2",
"jsdom": "^29.1.1",
"typescript": "^6.0.3",
"vite": "^8.0.14",
"vitest": "^4.1.7",
"web-vitals": "^5.2.0"
}
}