The following example shows how you can use Redux Beacon to track page views in an React app that uses Redux for state management, and React Router for navigation.
There is no limit to the number of middlewares or meta reducers you can create and use. So, to send analytics to multiple targets, create a middleware or a meta reducer for each target:
import { createMiddleware } from'redux-beacon';import Amplitude from'@redux-beacon/amplitude';import GoogleAnalytics from'@redux-beacon/google-analytics';import { amplitudeEvents, gaEvents } from'./my-event-definitions';constamplitudeMiddleware=createMiddleware(amplitudeEvents,Amplitude());constgaMiddleware=createMiddleware(gaEvents,GoogleAnalytics());// Apply both middlewares to the store
Likewise, for createMetaReducer:
import { createMetaReducer } from'redux-beacon';import Amplitude from'@redux-beacon/amplitude';import GoogleAnalytics from'@redux-beacon/google-analytics';import { amplitudeEvents, gaEvents } from'./my-event-definitions';constamplitudeMetaReducer=createMetaReducer(amplitudeEvents,Amplitude());constgaMetaReducer=createMetaReducer(gaEvents,GoogleAnalytics());// Add both meta reducers to the store
How to Create Your Own Target
Both createMiddleware and createMetaReducer require a target as their second parameter. A target is a function that Redux Beacon calls with an array of generated analytics events. What a target does with the array of generated events is up to the target's author, although the assumption is that the target will send those events to an external analytics service.
functionmyCustomTarget(events) {// - do something with the events.// - an event is usually an Object ({}), but doesn't have to be.// - an event should be serializable.// - events are what's returned from event definitions that you pair to action types. }
Most targets leverage an existing JavaScript sdk from an analytics service (e.g. Google Analytics), but some might post their own server requests.
// import an sdk, or install it as a global modulefunctionmyCustomTarget(events) {events.forEach(event => {switch (event.type) {case'some_event_type_you_define':window.mySDK.someMethod(event.paramA,event.paramB);break;case'some_other_event_type':window.mySDK.someOtherMethod(event.paramA);break;case'yet_another_event_type':fetch('https://my-domain.com/my/analytics/endpoint', { method:'POST', body:JSON.stringify(event.data), headers:newHeaders({'Content-Type':'application/json', }), });break;default:break; } });}
If your target relies on an SDK attached to window, it is good practice to first check that window exists to avoid issues during server side rendering.
If you decide to publish your target, please let us know so we can link to it in our docs.