Understanding the Analytics Key Infrastructure in OpenWork
The analytics key infrastructure in OpenWork is built around the analytics-key module, which dynamically resolves PostHog API keys through environment variable detection with intelligent fallbacks for production and development environments.
OpenWork implements a privacy-first telemetry system using PostHog to track application usage without exposing sensitive user data. The analytics key infrastructure, located in the different-ai/openwork repository, determines which analytics project receives events through a resolution mechanism defined in apps/app/src/app/lib/analytics-key.ts. This system enables self-hosted deployments and development builds to operate without sending data to third-party analytics platforms.
Core Architecture of the Analytics Key System
The infrastructure centers on a single resolver function that determines the active PostHog key at runtime based on build configuration and environment variables.
Key Resolution Logic
The resolvePosthogKey function in analytics-key.ts implements a priority-based selection system:
- Custom Environment Variable – If
VITE_OPENWORK_POSTHOG_KEYis set as a string, it is trimmed and used as-is, allowing custom project keys or explicit disabling via empty strings. - Development Fallback – In development builds (
import.meta.env.DEV === true), the function returns an empty string, effectively disabling analytics. - Production Default – Production builds use the hard-coded default key
phc_4YnPTlDVYPjgwKvLuNxhbHjV5kadgvd7XLzVHWnCXAI.
// apps/app/src/app/lib/analytics-key.ts
export const DEFAULT_POSTHOG_KEY = "phc_4YnPTlDVYPjgwKvLuNxhbHjV5kadgvd7XLzVHWnCXAI";
export function resolvePosthogKey(raw: unknown, isDev: boolean): string {
if (typeof raw === "string") return raw.trim();
return isDev ? "" : DEFAULT_POSTHOG_KEY;
}
Environment Variable Handling
The system relies on Vite's environment variable injection through import.meta.env. The analytics.ts module initializes the constant POSTHOG_KEY by invoking the resolver with the raw environment value and development flag:
// apps/app/src/app/lib/analytics.ts
const POSTHOG_KEY = resolvePosthogKey(
import.meta.env.VITE_OPENWORK_POSTHOG_KEY,
import.meta.env.DEV
);
This design ensures that builds are deterministic while allowing runtime configuration through the VITE_OPENWORK_POSTHOG_KEY variable.
Analytics Initialization and Event Flow
Once the key is resolved, the analytics client manages event queuing, batching, and transmission to PostHog's ingestion API.
Event Capture and Batching
The captureAnalyticsEvent function queues events locally and mirrors them to an in-app inspector for debugging. Events are flushed in batches of 50 (MAX_BATCH = 50) to the endpoint https://us.i.posthog.com/batch/. If the resolved key is an empty string or the user has disabled analytics via the Settings UI (analyticsEnabled flag), the function early-returns before any network activity occurs.
// Conceptual usage from apps/app/src/app/lib/analytics.ts
import { captureAnalyticsEvent, isAnalyticsEnabled } from "@/app/lib/analytics";
if (isAnalyticsEnabled()) {
captureAnalyticsEvent("feature_used", {
feature: "dark_mode",
duration_ms: 123,
});
}
Enterprise Gating
The analytics endpoint is protected by an "analytics" entitlement check. Servers return 402 Payment Required status codes when the current plan does not support telemetry features, preventing unauthorized usage of the infrastructure.
Configuration Examples
Overriding the Analytics Key in Production
Deploy OpenWork with a custom PostHog project key by setting the environment variable before building:
export VITE_OPENWORK_POSTHOG_KEY=phc_custom_key_12345
pnpm build
Disabling Analytics Completely
To ensure no telemetry data leaves the application, set the variable to an empty string:
export VITE_OPENWORK_POSTHOG_KEY=""
pnpm build
Development builds automatically disable analytics, but this method ensures production builds also operate without sending data.
Programmatic Key Resolution
For custom modules requiring direct access to the resolved key:
import { resolvePosthogKey } from "@/app/lib/analytics-key";
const posthogKey = resolvePosthogKey(
import.meta.env.VITE_OPENWORK_POSTHOG_KEY,
import.meta.env.DEV
);
if (posthogKey) {
console.log("Analytics active with key:", posthogKey);
} else {
console.log("Analytics disabled.");
}
Summary
- The analytics key infrastructure centers on
apps/app/src/app/lib/analytics-key.ts, which exportsresolvePosthogKeyandDEFAULT_POSTHOG_KEY. - Environment variable
VITE_OPENWORK_POSTHOG_KEYtakes precedence over all defaults, with empty strings explicitly disabling analytics. - Development builds automatically use empty keys to prevent local testing from polluting production datasets.
- Event batching occurs in chunks of 50 events to the PostHog
/batchendpoint, with network calls skipped when keys are empty or analytics are disabled. - Unit tests in
apps/app/tests/analytics-key.test.tsverify resolution logic across development, production, and custom override scenarios.
Frequently Asked Questions
How do I disable analytics in a self-hosted OpenWork instance?
Set the environment variable VITE_OPENWORK_POSTHOG_KEY to an empty string before building the application. According to the source code in analytics-key.ts, empty strings bypass the default production key and prevent the captureAnalyticsEvent function from initiating network requests.
What happens if I don't set VITE_OPENWORK_POSTHOG_KEY?
In production builds, the system falls back to the hard-coded DEFAULT_POSTHOG_KEY (phc_4YnPTlDVYPjgwKvLuNxhbHjV5kadgvd7XLzVHWnCXAI). In development builds, the resolver returns an empty string, effectively disabling analytics to prevent local development data from reaching the analytics platform.
Where is the analytics event data actually sent?
Events are batched and sent to https://us.i.posthog.com/batch/ using the resolved PostHog key. However, the transmission only occurs if the key is non-empty, the user has enabled analytics in settings, and the account has the required "analytics" entitlement. The implementation in analytics.ts ensures that no HTTP requests are made when these conditions are not met.
Can I use my own PostHog project with OpenWork?
Yes. Set VITE_OPENWORK_POSTHOG_KEY to your custom project API key during the build process. The resolvePosthogKey function treats any string value as a valid override, trimming whitespace and using it instead of the default production key. This allows enterprise users to direct analytics to self-hosted PostHog instances or separate project workspaces.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →