Middleware
Note
Middleware is only supported in Ampli legacy. Plugins replaced middleware in the latest Ampli version.
Middleware lets you extend Amplitude by running a sequence of custom code on every event. This pattern is flexible and you can use it to support event enrichment, transformation, filtering, routing to third-party destinations, and more.
Each middleware is a simple function with this signature:
function (payload: MiddlewarePayload: next: MiddlewareNext): void;
The payload
contains the event
to send and an optional extra
that lets you pass custom data to your own middleware implementations.
To invoke the next middleware in the queue, use the next
function.
You must call next(payload)
to continue the middleware chain. If a middleware doesn't call next
, then the event processing stops executing after the current middleware completes.
Add middleware to Ampli via ampli.client.addEventMiddleware()
. You can add as many middleware as you like. Each middleware runs in the order in which it's added.
Note
In Amplitude's Browser SDKs, add Middleware directly via ampli
instead of ampli.client
. To add Middleware in these
SDKs you should use ampli.addEventMiddlware()
.
const loggingMiddleware: Middleware = (payload, next) => {
console.log(`[ampli] event=${payload.event} extra=${payload.extra}`);
// continue to next middleware in chain
next(payload);
}
const filteringMiddleware: Middleware = (payload, next) => {
const {eventType} = payload.event;
if (shouldSendEvent(eventType)) {
next(payload)
} else {
// event will not continue to following middleware or be sent to Amplitude
console.log(`Filtered event: ${eventType}`);
}
}
ampli.client.addEventMiddleware(loggingMiddleware)
ampli.client.addEventMiddleware(filteringMiddleware)
Middleware examples¶
Modify events¶
ampli.client.addEventMiddleware((payload, next) => {
const { event } = payload;
if (hasPii(event.properties)) {
obfuscate(payload.event.properties);
}
next(payload);
});
Enrich events¶
ampli.client.addEventMiddleware((payload, next) => {
const { event } = payload;
if (needsDeviceId(event)) {
payload.event.deviceId = getDeviceId();
}
next(payload)
});
Basic filtering¶
ampli.client.addEventMiddleware((payload, next) => {
const { event } = payload;
if (event.name !== 'Event to Skip') {
next(payload);
}
});
Forward data to other services, but not Amplitude¶
import amplitude from 'amplitude/sdk'
import ampli = './ampli';
import adroll from 'adroll';
import segment from 'segment';
import snowplow from 'snowplow';
ampli.client.addEventMiddleware((payload, next) => {
const { event, extra } = payload;
segment.track(event.name, event.properties, { extra.anonymousId })
adroll.track();
snowplow.track(event.name, event.properties, extra.snowplow.context);
// next();
});
Use client-side validation¶
ampli.client.addEventMiddleware((payload, next) => {
if (isDevelopment && !SchemaValidator.isValid(payload.event)) {
throw Error(`Invalid event ${event.name}`);
}
next(payload);
});
ampli.client.addEventMiddleware((payload, next) => {
const { event, extra } = payload;
segment.track(event.name, event.properties, { extra.segment.anonymousId })
next(payload);
});
Still have questions? Ask them in the Community.