Codapult integrates with industry-standard observability tools — PostHog for product analytics, Sentry for error monitoring, OpenTelemetry for distributed tracing, and a built-in Core Web Vitals dashboard for performance tracking. Each integration is optional and activated by setting the corresponding environment variables.
PostHog Analytics
PostHog provides product analytics with event tracking, funnels, session replays, and feature flags.
Setup
Set two environment variables in .env.local:
NEXT_PUBLIC_POSTHOG_KEY="phc_your_project_key"
NEXT_PUBLIC_POSTHOG_HOST="https://us.i.posthog.com"
PostHog is automatically initialized when these variables are present. No code changes required.
Components
Analytics components live in src/components/analytics/ and handle:
- Page view tracking — automatic on route changes
- Custom event tracking — call
posthog.capture()for specific user actions
Built-in Analytics (Alternative)
If you prefer not to use PostHog, Codapult includes a first-party analytics module:
NEXT_PUBLIC_ANALYTICS_ENABLED="true"
This activates the self-hosted analytics engine in src/lib/analytics/, which tracks page views and custom events without sending data to a third party.
Sentry Error Monitoring
Sentry captures errors across the full stack — client-side React errors, server-side exceptions, and edge runtime failures.
Setup
| Variable | Description |
| ------------------------ | ------------------------------------------------ |
| NEXT_PUBLIC_SENTRY_DSN | Sentry DSN — activates error tracking when set |
| SENTRY_ORG | Organization slug (for source map uploads) |
| SENTRY_PROJECT | Project name (for source map uploads) |
| SENTRY_AUTH_TOKEN | Auth token (for source map uploads during build) |
Configuration Files
| File | Purpose |
| ----------------------------- | ---------------------------------------------------------------------------- |
| src/instrumentation.ts | Server-side Sentry initialization (Node.js runtime) |
| src/sentry.client.config.ts | Client-side Sentry initialization (browser) |
| src/sentry.server.config.ts | Server-side Sentry configuration |
| src/sentry.edge.config.ts | Edge runtime Sentry configuration |
| src/app/global-error.tsx | Global error boundary — catches unhandled React errors and reports to Sentry |
Source Maps
When SENTRY_ORG, SENTRY_PROJECT, and SENTRY_AUTH_TOKEN are set, source maps are automatically uploaded during pnpm build. This gives you readable stack traces in the Sentry dashboard instead of minified code references.
OpenTelemetry
OpenTelemetry provides distributed tracing for debugging request flows across services. The integration lives in src/lib/telemetry/.
Setup
| Variable | Required | Description |
| ----------------------------- | -------- | ----------------------------------------------------------------------- |
| OTEL_EXPORTER_OTLP_ENDPOINT | Yes | OTLP collector endpoint, e.g. http://localhost:4318 |
| OTEL_SERVICE_NAME | No | Service name in traces. Defaults to "codapult" |
| OTEL_TRACES_SAMPLE_RATE | No | Sampling rate from 0 to 1. Defaults to "0.1" (10%) |
| OTEL_EXPORTER_OTLP_HEADERS | No | Custom headers for the OTLP exporter, e.g. Authorization=Bearer token |
Tracing is disabled when OTEL_EXPORTER_OTLP_ENDPOINT is not set.
Compatible Backends
OpenTelemetry traces can be sent to any OTLP-compatible backend:
- Jaeger — open-source, self-hosted
- Datadog — commercial APM
- New Relic — commercial observability platform
- Grafana Tempo — open-source, pairs with Grafana dashboards
- Honeycomb — commercial observability with BubbleUp analysis
Example: Local Jaeger
# Start Jaeger with Docker
docker run -d --name jaeger \
-p 16686:16686 \
-p 4318:4318 \
jaegertracing/all-in-one:latest
OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
OTEL_SERVICE_NAME="my-saas"
OTEL_TRACES_SAMPLE_RATE="1.0"
Open http://localhost:16686 to view traces in the Jaeger UI.
Core Web Vitals
Codapult includes a performance reporter and in-memory metric store in src/lib/perf/. The admin panel displays a Core Web Vitals dashboard with real user metrics.
Tracked Metrics
| Metric | Full Name | What It Measures | Good Threshold | | -------- | ------------------------- | -------------------- | -------------- | | LCP | Largest Contentful Paint | Loading performance | ≤ 2.5s | | INP | Interaction to Next Paint | Responsiveness | ≤ 200ms | | CLS | Cumulative Layout Shift | Visual stability | ≤ 0.1 | | FCP | First Contentful Paint | Initial render speed | ≤ 1.8s | | TTFB | Time to First Byte | Server response time | ≤ 800ms |
Metrics are collected from real user sessions in the browser and reported to the server. View the aggregated results in the admin panel under Performance.
Choosing a Setup
| Stage | Recommended Setup | | --------------------- | ----------------------------------------------------------------- | | Local development | Built-in analytics + console errors (no external services needed) | | Staging | PostHog (free tier) + Sentry (free tier) | | Production | PostHog + Sentry + OpenTelemetry (with your preferred backend) |
All integrations are optional and independent — enable only what you need.
Next Steps
- Environment Variables — full reference for all monitoring-related env vars
- Admin Panel — view Core Web Vitals and manage experiments
- Security — rate limiting and error response guidelines