Skip to content
Open
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
6 changes: 6 additions & 0 deletions basics/javascript-web/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# PostHog Configuration
VITE_POSTHOG_KEY=phc_your_project_api_key_here
VITE_POSTHOG_HOST=https://us.i.posthog.com

# Optional: Enable debug mode to see PostHog requests in console
# VITE_POSTHOG_DEBUG=true
19 changes: 19 additions & 0 deletions basics/javascript-web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Dependencies
node_modules/

# Build output
dist/

# Environment variables
.env
.env.local

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db
137 changes: 137 additions & 0 deletions basics/javascript-web/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# PostHog JavaScript Example - Browser Todo App

A simple browser-based todo application built with vanilla JavaScript and Vite, demonstrating PostHog integration for non-framework JavaScript projects.

## Purpose

This example serves as:
- **Verification** that the context-mill wizard works for plain JavaScript projects
- **Reference implementation** of PostHog best practices for vanilla JS browser apps
- **Working example** you can run and modify

## Features Demonstrated

- **PostHog initialization** - `posthog.init()` with `api_host` configuration
- **Autocapture** - Automatic tracking of clicks, form submissions, and pageviews (enabled by default)
- **Custom event tracking** - Manual `posthog.capture()` calls with event properties
- **User identification** - `posthog.identify()` on login and `posthog.reset()` on logout
- **Error tracking** - `posthog.captureException()` for unhandled errors and promise rejections

## Quick Start

### 1. Install Dependencies

```bash
npm install
```

### 2. Configure PostHog

```bash
# Copy environment template
cp .env.example .env

# Edit .env and add your PostHog API key
# VITE_POSTHOG_KEY=phc_your_api_key_here
# VITE_POSTHOG_HOST=https://us.i.posthog.com
```

### 3. Run the App

```bash
npm run dev
```

Open http://localhost:3000 in your browser.

## What Gets Tracked

The app tracks these custom events in PostHog (in addition to autocaptured clicks and pageviews):

| Event | Properties | Purpose |
|-------|-----------|---------|
| `todo_added` | `todo_id`, `text_length`, `total_todos` | When user adds a new todo |
| `todo_completed` | `todo_id`, `time_to_complete_hours` | When user completes a todo |
| `todo_deleted` | `todo_id`, `was_completed` | When user deletes a todo |
| `user_logged_in` | (none) | When user logs in |
| `user_logged_out` | (none) | When user logs out |

## Code Structure

```
basics/javascript/
├── index.html # Entry HTML page
├── package.json # Dependencies (posthog-js, vite)
├── vite.config.js # Vite configuration
├── .env.example # Environment variable template
├── .gitignore # Git ignore rules
├── README.md # This file
└── src/
├── posthog.js # PostHog initialization (import this first)
├── main.js # Todo app logic with event tracking
└── style.css # App styles
```

## Key Implementation Patterns

### 1. Initialization (posthog.js)

```javascript
import posthog from 'posthog-js'

posthog.init('your-api-key', {
api_host: 'https://us.i.posthog.com',
})
```

Initialize PostHog once, early in your app. All other modules import the same instance.

### 2. Event Tracking

```javascript
// Track events with properties — never send PII or user-generated content
posthog.capture('event_name', {
item_count: 5, // Metadata is OK
action_type: 'create', // Categories are OK
})
```

### 3. User Identification

```javascript
// On login — links events to a known user
posthog.identify('user_123')

// On logout — resets to a new anonymous distinct_id
posthog.reset()
```

### 4. Error Tracking

```javascript
// Global error handlers
window.addEventListener('error', (event) => {
posthog.captureException(event.error)
})

window.addEventListener('unhandledrejection', (event) => {
posthog.captureException(event.reason)
})
```

## Running Without PostHog

The app works fine without PostHog configured. You'll see a console warning but the app continues to function normally.

## Next Steps

- Modify the app to experiment with PostHog tracking
- Explore feature flags: `posthog.isFeatureEnabled('flag-key')`
- Check your PostHog dashboard to see tracked events and autocaptured data
- Try session recording (enable in PostHog project settings)

## Learn More

- [PostHog JavaScript SDK Documentation](https://posthog.com/docs/libraries/js)
- [PostHog JavaScript SDK API Reference](https://posthog.com/docs/references/posthog-js)
- [PostHog Product Analytics](https://posthog.com/docs/product-analytics)
42 changes: 42 additions & 0 deletions basics/javascript-web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Todo App - PostHog JavaScript Example</title>
<link rel="stylesheet" href="/src/style.css" />
</head>
<body>
<div id="app">
<header>
<h1>Todo App</h1>
<div id="auth-section">
<div id="logged-out">
<input type="text" id="username-input" placeholder="Enter username" />
<button id="login-btn">Log In</button>
</div>
<div id="logged-in" hidden>
<span id="username-display"></span>
<button id="logout-btn">Log Out</button>
</div>
</div>
</header>

<main>
<form id="todo-form">
<input type="text" id="todo-input" placeholder="What needs to be done?" required />
<button type="submit">Add</button>
</form>

<ul id="todo-list"></ul>

<div id="stats">
<span id="total-count">0 items</span>
<span id="completed-count">0 completed</span>
</div>
</main>
</div>

<script type="module" src="/src/main.js"></script>
</body>
</html>
17 changes: 17 additions & 0 deletions basics/javascript-web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "posthog-javascript-example",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"posthog-js": "^1.187.0"
},
"devDependencies": {
"vite": "^6.0.0"
}
}
Loading
Loading