PostHog Integration Guide
PostHog Analytics Integration
Section titled “PostHog Analytics Integration”This document describes how surkyl.com integrates with PostHog using the godseye-proxy service.
Overview
Section titled “Overview”surkyl.com uses godseye-proxy as a reverse proxy for PostHog Cloud. This provides:
- Ad blocker bypass - Uses
e.surkyl.cominstead ofus.i.posthog.com - First-party tracking - Better privacy compliance
- Large payload support - Handles up to 64MB for session recordings
- Production-grade - Health checks, metrics, and proper error handling
Architecture
Section titled “Architecture”┌─────────────────────────────────────────────────────────────┐│ Browser (surkyl.com) ││ ↓ ││ posthog.init('phc_xxx', { ││ api_host: 'https://e.surkyl.com', ││ ui_host: 'https://us.posthog.com' ││ }) │└─────────────────────────────────────────────────────────────┘ ↓┌─────────────────────────────────────────────────────────────┐│ DNS: e.surkyl.com → godseye-proxy server │└─────────────────────────────────────────────────────────────┘ ↓┌─────────────────────────────────────────────────────────────┐│ godseye-proxy (Port 64980) ││ - Forwards requests to PostHog ││ - Overrides Host header ││ - Handles CORS │└─────────────────────────────────────────────────────────────┘ ↓┌─────────────────────────────────────────────────────────────┐│ PostHog Cloud (us.i.posthog.com) │└─────────────────────────────────────────────────────────────┘Configuration
Section titled “Configuration”Environment Variables
Section titled “Environment Variables”Add these to your .env file (see .env.example):
# Required: Your PostHog project keyPUBLIC_POSTHOG_KEY=phc_your_project_key_here
# Required: godseye-proxy URL# Production: https://postit.godseye.surkyl.com# Development: http://localhost:64980 (if running godseye-proxy locally)PUBLIC_POSTHOG_PROXY_HOST=https://postit.godseye.surkyl.com
# Optional: Environment (defaults to 'development')PUBLIC_ENV=production
# Optional: Enable PostHog in development (disabled by default)PUBLIC_POSTHOG_ENABLED=trueRuntime Environment Variables:
With Astro’s SSR mode and the Node adapter, environment variables are read from process.env at runtime. This means:
- ✅ You can change environment variables in Dokploy/Docker
- ✅ Changes take effect after restarting the container (no rebuild needed)
- ✅ Same build can be deployed to different environments with different configs
- ✅ Environment variables are read fresh on each request
PostHog Client
Section titled “PostHog Client”The PostHog client is configured in src/components/posthog.astro:
posthog.init(posthogKey, { api_host: posthogApiHost, // e.surkyl.com (via env var) ui_host: 'https://us.posthog.com', // For toolbar/feature flags person_profiles: 'identified_only', capture_pageview: true, capture_pageleave: true, debug: false,});Local Development
Section titled “Local Development”Option 1: Run godseye-proxy Locally (Recommended)
Section titled “Option 1: Run godseye-proxy Locally (Recommended)”Terminal 1: Start godseye-proxy
cd apps/godseye-proxynx serve godseye-proxy# Runs on http://localhost:64980Terminal 2: Start surkyl-com
cd apps/surkyl-com# In your .env file:# PUBLIC_POSTHOG_PROXY_HOST=http://localhost:64980# PUBLIC_POSTHOG_ENABLED=truenx serve surkyl-comOption 2: Use Production Proxy
Section titled “Option 2: Use Production Proxy”Point your local dev environment to the production godseye-proxy:
PUBLIC_POSTHOG_PROXY_HOST=https://e.surkyl.comPUBLIC_POSTHOG_ENABLED=trueOption 3: Disable PostHog
Section titled “Option 3: Disable PostHog”Don’t set PUBLIC_POSTHOG_ENABLED in your .env file. PostHog will be disabled in development mode.
Testing
Section titled “Testing”1. Open Browser DevTools
Section titled “1. Open Browser DevTools”Navigate to http://localhost:4321 and open the console.
2. Verify PostHog Loaded
Section titled “2. Verify PostHog Loaded”window.posthog;// Should return PostHog object (not undefined)3. Check Network Requests
Section titled “3. Check Network Requests”Open the Network tab and filter by “localhost:64980” or “e.surkyl.com”:
- Look for requests to
/static/array.js(PostHog script) - Look for requests to
/decide/(PostHog config) - Look for requests to
/e/or/batch/(events)
All requests should go through godseye-proxy, NOT directly to us.i.posthog.com.
4. Send Test Event
Section titled “4. Send Test Event”posthog.capture('test_event', { test: true, timestamp: new Date().toISOString(),});Check the Network tab for a new request.
5. Verify in PostHog Dashboard
Section titled “5. Verify in PostHog Dashboard”- Go to https://us.posthog.com
- Navigate to Events
- Look for
$pageviewandtest_eventevents - Events should appear within 5-10 seconds
Production Deployment
Section titled “Production Deployment”Prerequisites
Section titled “Prerequisites”-
Deploy godseye-proxy to your server
- See godseye-proxy/README.md for deployment instructions
- Configuration is at
configs/godseye/godseye.config.yml(repo root) - Ensure it’s running on port 64980
-
Configure DNS
e.surkyl.com → A/CNAME → [godseye-proxy-server-ip] -
Setup SSL/TLS
- Use Cloudflare, Caddy, or nginx to terminate SSL
- Ensure
https://e.surkyl.comis accessible
Deployment Checklist
Section titled “Deployment Checklist”- godseye-proxy deployed and running
- DNS
e.surkyl.compointing to godseye-proxy server - SSL/TLS configured (https://e.surkyl.com accessible)
- godseye-proxy health check responding:
https://e.surkyl.com/health - Environment variables set in production:
Terminal window PUBLIC_POSTHOG_KEY=phc_your_project_key_herePUBLIC_POSTHOG_PROXY_HOST=https://e.surkyl.comPUBLIC_ENV=production - surkyl-com deployed with new env vars
- Test with ad blocker enabled (should still work!)
- Verify events in PostHog dashboard
Monitoring
Section titled “Monitoring”Health Checks
Section titled “Health Checks”godseye-proxy exposes a health endpoint:
curl https://e.surkyl.com/health# {"status":"healthy","service":"godseye-proxy"}Use this for:
- Docker healthchecks
- Kubernetes liveness probes
- Uptime monitoring
Metrics
Section titled “Metrics”godseye-proxy exposes Prometheus metrics:
curl https://e.surkyl.com/metricsgodseye-proxy logs in JSON format (configurable):
# View logsdocker logs godseye-proxy
# Follow logsdocker logs -f godseye-proxyTroubleshooting
Section titled “Troubleshooting”Events Not Reaching PostHog
Section titled “Events Not Reaching PostHog”- Check godseye-proxy logs for errors
- Verify DNS points to godseye-proxy:
dig e.surkyl.com - Check SSL certificate:
curl -I https://e.surkyl.com/health - Verify env var
PUBLIC_POSTHOG_PROXY_HOSTis set correctly - Test godseye-proxy directly:
Terminal window curl https://e.surkyl.com/health
CORS Errors in Browser
Section titled “CORS Errors in Browser”Update godseye-proxy config (apps/godseye-proxy/configs/godseye.config.yml):
cors: allow_origins: - 'https://surkyl.com' - 'https://www.surkyl.com' - 'http://localhost:4321' # For developmentRestart godseye-proxy after config changes.
PostHog Toolbar Not Working
Section titled “PostHog Toolbar Not Working”The PostHog toolbar authenticates via ui_host. Ensure it’s set correctly:
posthog.init(posthogKey, { api_host: 'https://e.surkyl.com', // Proxied ui_host: 'https://us.posthog.com', // Direct (do NOT proxy this)});Large Session Recordings Failing
Section titled “Large Session Recordings Failing”godseye-proxy supports up to 64MB payloads by default. If you need more:
Update godseye-proxy config:
limits: max_body_size: 134217728 # 128MBRestart godseye-proxy.
Ad Blocker Still Blocking
Section titled “Ad Blocker Still Blocking”-
Check subdomain name - Don’t use obvious tracking names like:
- ❌
analytics.surkyl.com - ❌
tracking.surkyl.com - ❌
posthog.surkyl.com - ✅
e.surkyl.com(good!)
- ❌
-
Verify requests go through proxy:
- Open Network tab
- Requests should go to
e.surkyl.com - NOT to
us.i.posthog.com
-
Test with different ad blockers:
- uBlock Origin
- AdBlock Plus
- Brave Browser
Migration Notes
Section titled “Migration Notes”Previous Setup:
- Used custom Astro endpoint:
src/pages/ingest/[...path].ts - Requests went to
/ingest/*on same domain - Limited to Astro’s default payload size
Current Setup:
- Uses dedicated godseye-proxy service
- Requests go to
e.surkyl.com(or configured proxy host) - Supports up to 64MB payloads
- Production-grade with health checks and metrics
What Changed:
- Removed
src/pages/ingest/[...path].ts(custom proxy) - Updated
src/components/posthog.astro(use env var for proxy host) - Added
PUBLIC_POSTHOG_PROXY_HOSTenv var - Added godseye-proxy configuration
References
Section titled “References”Support
Section titled “Support”For issues or questions:
- Check godseye-proxy logs
- Review this documentation
- Check PostHog dashboard for events
- Review the migration plan for rollback procedures