Fastify
Contents
Use the PostHog Node.js SDK to capture events and request errors from your Fastify app.
Installation
Install the SDK in your Fastify app:
This guide uses Fastify 5 and posthog-node 5.52.1 on Node.js. Get your project token and API host from your project settings.
Set up PostHog
Create one PostHog client for your app. Register the hooks and error handler in the same Fastify scope as your routes, before those routes.
Process-level enableExceptionAutocapture does not capture errors that Fastify handles. Use setErrorHandler to capture these errors.
Request context and identity
Keep onRequest callback-based, not async. Calling done inside withContext continues the request in that context. { fresh: true } prevents inheritance from an outer context.
request.user belongs to your application. It is not a built-in Fastify identity. Populate it with a verified user and a string id in an earlier authentication hook. Without authentication, this example captures exceptions without creating person profiles.
If authentication runs later, pass the verified ID directly to captureException instead of undefined.
Do not use x-posthog-distinct-id as proof of identity. Tracing headers are client-controlled analytics values, and this example does not read them. To link Session Replay, you can explicitly add a validated sessionId to the context. Never use it for authorization.
Capture events
Add this route before app.listen() to capture an event for an authenticated request. The event inherits the verified identity and request properties from withContext.
See the Node.js capture documentation for more event options.
Error handling
The HTTP status filter is optional application logic, not an SDK default. Remove the if condition to capture handled 4xx errors too. Unknown-route 404 responses do not pass through setErrorHandler.
If you already have an error handler, add the capture call there instead of replacing your response behavior. Avoid capturing the same error again in another hook.
The example records the route pattern, not the raw URL. This avoids collecting query strings or path parameter values. Review error messages and other properties for sensitive data before capture.
Fastify's default error response includes the error message. Use your application's response policy to hide internal details.
Shutdown
During graceful termination, call await app.close() from your application's shutdown handler. Fastify then runs onClose, which waits for PostHog to drain buffered events.
Do not call shutdown() per request. Do not exit the process before it finishes. Abrupt termination can lose queued events.
Next steps
See the Node.js SDK documentation for Feature Flags, group analytics, and other SDK features.