|
| 1 | +# PostHog TanStack Start example |
| 2 | + |
| 3 | +This is a [TanStack Start](https://tanstack.com/start) example demonstrating PostHog integration with product analytics, session replay, feature flags, and error tracking. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- **Product analytics**: Track user events and behaviors |
| 8 | +- **Session replay**: Record and replay user sessions |
| 9 | +- **Error tracking**: Capture and track errors automatically |
| 10 | +- **User authentication**: Demo login system with PostHog user identification |
| 11 | +- **Server-side & client-side tracking**: Complete examples of both tracking methods |
| 12 | +- **Reverse proxy**: PostHog ingestion through Vite dev server proxy |
| 13 | + |
| 14 | +## Getting started |
| 15 | + |
| 16 | +### 1. Install dependencies |
| 17 | + |
| 18 | +```bash |
| 19 | +npm install |
| 20 | +``` |
| 21 | + |
| 22 | +### 2. Configure environment variables |
| 23 | + |
| 24 | +Create a `.env` file in the root directory: |
| 25 | + |
| 26 | +```bash |
| 27 | +VITE_POSTHOG_KEY=your_posthog_project_api_key |
| 28 | +VITE_POSTHOG_HOST=https://us.i.posthog.com |
| 29 | +``` |
| 30 | + |
| 31 | +Get your PostHog API key from your [PostHog project settings](https://app.posthog.com/project/settings). |
| 32 | + |
| 33 | +### 3. Run the development server |
| 34 | + |
| 35 | +```bash |
| 36 | +npm run dev |
| 37 | +``` |
| 38 | + |
| 39 | +Open [http://localhost:3000](http://localhost:3000) with your browser to see the app. |
| 40 | + |
| 41 | +## Project structure |
| 42 | + |
| 43 | +``` |
| 44 | +src/ |
| 45 | +├── components/ |
| 46 | +│ └── Header.tsx # Navigation header with auth state |
| 47 | +├── contexts/ |
| 48 | +│ └── AuthContext.tsx # Authentication context with PostHog integration |
| 49 | +├── lib/ |
| 50 | +│ ├── posthog-client.ts # Client-side PostHog initialization |
| 51 | +│ └── posthog-server.ts # Server-side PostHog client |
| 52 | +├── routes/ |
| 53 | +│ ├── __root.tsx # Root route with AuthProvider |
| 54 | +│ ├── index.tsx # Home/login page |
| 55 | +│ ├── burrito.tsx # Demo feature page with event tracking |
| 56 | +│ ├── profile.tsx # User profile with error tracking demo |
| 57 | +│ ├── api/ |
| 58 | +│ │ └── auth/ |
| 59 | +│ │ └── login.ts # Login API with server-side tracking |
| 60 | +│ └── _demo/ # TanStack Start demo examples |
| 61 | +└── styles.css # Global styles |
| 62 | +
|
| 63 | +vite.config.ts # Vite config with PostHog proxy |
| 64 | +.env # Environment variables |
| 65 | +``` |
| 66 | + |
| 67 | +## Key integration points |
| 68 | + |
| 69 | +### Client-side initialization |
| 70 | + |
| 71 | +PostHog is initialized on the client side in `lib/posthog-client.ts`: |
| 72 | + |
| 73 | +```typescript |
| 74 | +import posthog from 'posthog-js' |
| 75 | + |
| 76 | +export function initPostHog() { |
| 77 | + if (typeof window !== 'undefined') { |
| 78 | + posthog.init(import.meta.env.VITE_POSTHOG_KEY!, { |
| 79 | + api_host: '/ingest', |
| 80 | + ui_host: import.meta.env.VITE_POSTHOG_HOST || 'https://us.posthog.com', |
| 81 | + defaults: '2025-05-24', |
| 82 | + capture_exceptions: true, |
| 83 | + debug: import.meta.env.DEV, |
| 84 | + loaded: (posthog) => { |
| 85 | + if (import.meta.env.DEV) posthog.debug() |
| 86 | + }, |
| 87 | + }) |
| 88 | + } |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +The initialization happens in the root route's `useEffect` hook to ensure it runs only in the browser. |
| 93 | + |
| 94 | +### Server-side setup |
| 95 | + |
| 96 | +For server-side tracking, we use the `posthog-node` SDK with a singleton pattern: |
| 97 | + |
| 98 | +```typescript |
| 99 | +import { PostHog } from 'posthog-node' |
| 100 | + |
| 101 | +export function getPostHogClient() { |
| 102 | + if (!posthogClient) { |
| 103 | + posthogClient = new PostHog( |
| 104 | + process.env.VITE_POSTHOG_KEY || import.meta.env.VITE_POSTHOG_KEY!, |
| 105 | + { |
| 106 | + host: process.env.VITE_POSTHOG_HOST || import.meta.env.VITE_POSTHOG_HOST, |
| 107 | + flushAt: 1, // Send immediately |
| 108 | + flushInterval: 0 // No batching delay |
| 109 | + } |
| 110 | + ) |
| 111 | + } |
| 112 | + return posthogClient |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +This client is used in API routes to track server-side events. |
| 117 | + |
| 118 | +### Reverse proxy configuration |
| 119 | + |
| 120 | +The Vite dev server is configured to proxy PostHog requests to avoid CORS issues and improve reliability: |
| 121 | + |
| 122 | +```typescript |
| 123 | +server: { |
| 124 | + proxy: { |
| 125 | + '/ingest': { |
| 126 | + target: 'https://us.i.posthog.com', |
| 127 | + changeOrigin: true, |
| 128 | + rewrite: (path) => path.replace(/^\/ingest/, ''), |
| 129 | + secure: false, |
| 130 | + }, |
| 131 | + }, |
| 132 | +} |
| 133 | +``` |
| 134 | + |
| 135 | +This setup: |
| 136 | +- Avoids CORS issues |
| 137 | +- Bypasses ad blockers that might block PostHog |
| 138 | +- Improves data collection reliability |
| 139 | +- Keeps all requests on the same domain |
| 140 | + |
| 141 | +### Authentication flow |
| 142 | + |
| 143 | +1. User enters credentials on home page (`/`) |
| 144 | +2. Form submits to `/api/auth/login` API route |
| 145 | +3. Server captures `server_login` event with PostHog |
| 146 | +4. Client identifies user and captures `user_logged_in` event |
| 147 | +5. User is redirected to authenticated pages |
| 148 | + |
| 149 | +### User identification |
| 150 | + |
| 151 | +```typescript |
| 152 | +// User identification on login |
| 153 | +posthog.identify(username, { |
| 154 | + username: username, |
| 155 | +}) |
| 156 | +``` |
| 157 | + |
| 158 | +### Event tracking |
| 159 | + |
| 160 | +```typescript |
| 161 | +// Custom event tracking |
| 162 | +posthog.capture('burrito_considered', { |
| 163 | + total_considerations: user.burritoConsiderations + 1, |
| 164 | + username: user.username, |
| 165 | +}) |
| 166 | +``` |
| 167 | + |
| 168 | +### Error tracking |
| 169 | +```typescript |
| 170 | +// Error tracking |
| 171 | +posthog.captureException(error) |
| 172 | +``` |
| 173 | + |
| 174 | +## Learn more |
| 175 | + |
| 176 | +- [PostHog documentation](https://posthog.com/docs) |
| 177 | +- [TanStack Start documentation](https://tanstack.com/start) |
| 178 | +- [TanStack Router documentation](https://tanstack.com/router) |
| 179 | +- [PostHog React integration](https://posthog.com/docs/libraries/react) |
| 180 | +- [PostHog Node.js integration](https://posthog.com/docs/libraries/node) |
0 commit comments