Prerequisites
- An OTel collector available and reachable, ingesting into your Managed ClickStack service. You need its OTLP endpoint and an ingestion token.
- Node 18+ and npm.
1
Clone and run the application
Clone the repository, install dependencies, and create your The ClickHouse data source defaults to the public read-only demo cluster, so the app runs without any further configuration. Start it:Open http://localhost:5001. You will see a year selector, summary statistics, an activity chart, top users and domains tables, and a search box. Click around: switch years, drill into stories.
At this point the application is running but uninstrumented. ClickStack shows no data: it is waiting for telemetry. This is the “before” state.
.env file:
2
Get the connection details
The application needs two values to reach the collector:The SDK uses
OTEL_EXPORTER_OTLP_ENDPOINT: the OTLP endpoint your collector exposes (commonly port4318for OTLP over HTTP).OTEL_EXPORTER_OTLP_HEADERS: the authorization header carrying your ingestion token, in the formauthorization=<token>.
.env and set them:OTEL_EXPORTER_OTLP_HEADERS to set the authorization header for all three signals: traces, metrics, and logs. If your collector runs locally and doesn’t enforce auth, you can leave the value empty (OTEL_EXPORTER_OTLP_HEADERS=authorization=), but the variable must be present; the SDK skips initialization entirely if it’s unset or fully empty.3
Instrument the application
Instrumentation has three parts: install the SDKs, switch the launch command, and enable the browser SDK. None of it changes the application’s business logic.That is the entire backend change. The auto-instrumentation is loaded by No extra
Install the SDKs
Install both the backend and browser OpenTelemetry SDKs:Use the opentelemetry-instrument CLI
The application is launched byrun.sh, which has two exec lines at the bottom: one active, one commented. Switch which one is active so Node is wrapped by opentelemetry-instrument:opentelemetry-instrument at process start.Enable the browser SDK
To capture distributed traces (browser to backend) and session replays, enable the browser SDK insrc/web/telemetry.ts. Uncomment the import and the HyperDX.init({...}) block:.env edits are required. __OTLP_ENDPOINT__ and __OTLP_AUTH_TOKEN__ are compile-time constants injected by vite.config.ts: the endpoint is OTEL_EXPORTER_OTLP_ENDPOINT and the token is parsed out of OTEL_EXPORTER_OTLP_HEADERS, the same values the backend uses.4
Generate traffic and view telemetry
Restart the application so the new launch command and freshly built browser bundle take effect:Reload the browser tab so Vite serves the updated bundle, then refresh the app a few times, switch years, and click into stories to generate traffic.Open the ClickStack UI:


Logs, metrics, traces, and session replays all land in the same UI, share the same query language, and are correlated automatically.
- Go to Search and filter to the last 5 minutes. Logs for
hn-analyzer-apistream in.

- Click into a request and walk up the trace. You will see the Express handler span, a child HTTP span pointing at the ClickHouse cluster with real network duration, and correlated
console.logrecords on the same trace.

- Open Session Replay to play back a scrubbable video of a browser session, synced to the trace timeline.

Learn more
- Session Replay: feature overview, SDK options, and privacy controls.
- Session Replay Demo: a self-contained demo with a local ClickStack instance.
- ClickStack Getting Started: deploy ClickStack and ingest your first data.
- All Sample Datasets: other example datasets and guides.