analytics.js
analytics.js copied to clipboard
analytics.js traits behave differently to Analytics for Android
I'm designing our segment.io web integration and in the process I've found that analytics.js behaves differently to Analytics for Android with regards to traits.
The Android Identify documentation says:
Additionally, traits are sent in the context.traits field with every message.
For example:
window.analytics.indentify({
first_name: 'Barry',
last_name: 'From Eastenders'
});
// Sends
{
// ...
"type": "identify",
"context": {
// ...
},
"traits": {
"first_name": "Barry",
"last_name": "From Eastenders"
}
}
Then a subsequent call to track or page:
window.analytics.track('Button Clicked', { button_name: 'Support' });
// Sends
{
// ...
"type": "track",
"context": {
// ...
// Analytics for Android includes the traits from our previous identify call here, but analytics.js does not
// "traits": {
// "first_name": "Barry",
// "last_name": "From Eastenders"
// }
},
"properties": {
"button_name": "Support"
}
}
I'm not sure what iOS Analytics does or if the SDKs differ by design but I think it's a feature we'd like.
I have implemented it via a middleware, but before I went ahead with this it would be good to get some feed back re: why it's not done by default / whether it's a good or bad practice?
window.analytics.addSourceMiddleware(({ payload, next }) => {
const traits = window.analytics.user().traits();
payload.obj.context.traits = {
...traits,
...payload.obj.context.traits
};
next(payload);
});
I'm facing the same issue. Analytics iOS does do that. Analytics.JS is the only one falling out of the bucket here
@pbassut we're using the following middleware in production which seems to be working ok.
export const contextTraitsMiddleware = () =>
createMiddleware(({ payload, next }) => {
const traits = window.analytics.user().traits();
switch (payload.action()) {
case 'page':
case 'track':
payload.obj.context.traits = {
...traits,
...payload.obj.context.traits
};
break;
}
next(payload);
});
// ...
window.analytics.addSourceMiddleware(contextTraitsMiddleware());
const createMiddleware = (
fn: (input: SegmentAnalytics.SourceMiddlewareInput) => void
) => (input: Parameters<typeof fn>[0]) => {
// Wait until analytics is ready so we can access the full API (e.g. window.analytics.user().traits())
window.analytics.ready(() => {
try {
fn(input);
} catch (ex) {
// Report errors to our servers (and the console) as segment appears to swallow them (perhaps they report it to their own servers?)
reportError(ex);
throw ex;
}
});
};