Express SDK
Auto-track every HTTP request and server error with two middleware lines. Includes a shared SDK instance on req.fa.
The Express package creates requestMiddleware and errorMiddlewarethat automatically send request and server_error events. It also attaches the SDK instance to req.fa for manual tracking in routes.
Installation
Install the package
npm install @flash-analytics/express@2.1.9pnpm add @flash-analytics/express@2.1.9Set environment variables
FLASH_CLIENT_ID=00000000-0000-4000-8000-000000000000
FLASH_CLIENT_SECRET=your-secret-keyAdd middleware to your app
Register requestMiddleware before your routes and errorMiddlewareafter all routes (standard Express error-handler position).
import express from 'express';
import { createFlashAnalytics } from '@flash-analytics/express';
const app = express();
const { sdk, requestMiddleware, errorMiddleware } = createFlashAnalytics({
clientId: process.env.FLASH_CLIENT_ID!,
clientSecret: process.env.FLASH_CLIENT_SECRET,
resolveUserId: (req) => (req as any).user?.id,
shouldCaptureExpressRequest: (req) => !req.path.startsWith('/health'),
shouldCaptureError: (err) => err.name !== 'ValidationError',
});
// Must be before routes
app.use(requestMiddleware);
// Your routes here
app.get('/', (req, res) => res.json({ ok: true }));
// Must be after all routes
app.use(errorMiddleware);
app.listen(3000);Middleware order matters
requestMiddleware must come before your routes. errorMiddleware must come after all routes — this is standard Express error handler convention.Track custom events per route
Use req.fa to send route-specific events from any handler.
app.post('/checkout', async (req, res) => {
req.fa.track('checkout_created', {
profileId: req.user?.id,
orderId: req.body.orderId,
cartValue: req.body.total,
});
// Process checkout...
res.json({ ok: true });
});Auto-captured events
requestSent for every HTTP request that passes the shouldCaptureExpressRequest filter. Includes method, path, status code, and resolved user ID.
server_errorSent for errors that reach the error middleware and pass the shouldCaptureError filter. Includes error name and stack.
Configuration options
clientIdRequiredYour Flash app UUID (same as appId in other SDKs).
clientSecretOptional secret sent as flash-analytics-client-secret. Keep server-only.
resolveUserId(req)Map an Express request to a Flash profileId.
shouldCaptureExpressRequest(req)Return false to skip automatic request events (e.g. health checks).
shouldCaptureError(err, req)Return false to skip automatic server_error events (e.g. validation errors).
debugLogs background tracking status. Use in development only.
onTrackSuccess(eventName, response)Callback after middleware event succeeds.
onTrackError(eventName, error)Callback after middleware event fails.
Using the SDK directly
The returned sdk instance is a full FlashAnalytics instance. Use it outside of request contexts (e.g. startup events, scheduled jobs).
const { sdk } = createFlashAnalytics({ clientId: process.env.FLASH_CLIENT_ID! });
// At server startup
sdk.track('server_started', { version: process.env.npm_package_version });
// In a cron job
sdk.track('daily_report_generated', { reportDate: today });Batching and shutdown flush
Use createFlashAnalytics when you enable batching so middleware events, manual route events, and shutdown flushing share one SDK instance.
const { sdk, requestMiddleware, errorMiddleware } = createFlashAnalytics({
clientId: process.env.FLASH_CLIENT_ID!,
clientSecret: process.env.FLASH_CLIENT_SECRET,
deliveryStrategy: {
strategy: 'batching',
config: {
size: 25,
timeout: 5000,
fallbackToIndividual: true,
},
},
});
process.on('SIGTERM', () => {
void sdk.flushBatch();
});Dashboard collection controls and session timeout
The Express SDK inherits the core SDK collection pipeline. It can use dashboard-managed event rules, strip blocked properties locally, apply batching defaults, and send a per-client session timeout override to the backend.
createFlashAnalytics({
clientId: process.env.FLASH_CLIENT_ID!,
clientSecret: process.env.FLASH_CLIENT_SECRET,
collectionConfig: true,
maxSessionTimeoutInMin: 15,
});Allow events:
request
server_error
checkout_created
invoice.*
Block events:
health_check
debug.*
For request, block properties:
authorization
cookie
rawBody
Client-level override for api-prod:
do not capture /health
block property xInternalTraceId
batching: 25 events or 5 secondsSession access
app.get('/session', (req, res) => {
const session = req.fa.getSession();
res.json({ sessionId: session?.id });
});