@hakimio/ngx-google-analytics
Version:
A simple Google Analytics wrapper for Angular apps
54 lines • 9.66 kB
JavaScript
import { APP_BOOTSTRAP_LISTENER } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter, skip } from 'rxjs';
import { GoogleAnalyticsService } from '../services/google-analytics.service';
import { NGX_GOOGLE_ANALYTICS_ROUTING_SETTINGS_TOKEN } from '../tokens/ngx-google-analytics-router-settings-token';
/**
* Provide a DI Configuration to attach GA Trigger to Router Events at Angular Startup Cycle.
*/
export const NGX_GOOGLE_ANALYTICS_ROUTER_INITIALIZER_PROVIDER = {
provide: APP_BOOTSTRAP_LISTENER,
multi: true,
useFactory: GoogleAnalyticsRouterInitializer,
deps: [
NGX_GOOGLE_ANALYTICS_ROUTING_SETTINGS_TOKEN,
GoogleAnalyticsService
]
};
/**
* Attach a listener to `NavigationEnd` Router event. So, every time Router finish the page resolution it should call `NavigationEnd` event.
* We assume that NavigationEnd is the final page resolution and call GA `page_view` command.
*
* To avoid double binds, we also destroy the subscription when de Bootstrap Component is destroyed. But, we don't know for sure
* that this strategy does not cause double bind on multiple bootstrap components.
*
* We are using the component's injector reference to resolve Router, so I hope there is no problem with double binding.
*
* If you have this problem, I encourage not Use NgxGoogleAnalyticsRouterModule and attach the listener on AppComponent initialization.
*/
export function GoogleAnalyticsRouterInitializer(settings, gaService) {
return (c) => {
const router = c.injector.get(Router);
const { include = [], exclude = [] } = settings ?? {};
const includeRules = normalizePathRules(include);
const excludeRules = normalizePathRules(exclude);
const subs = router
.events
.pipe(filter((event) => event instanceof NavigationEnd), skip(1), // Prevent double views on the first trigger (because GA Already send one ping on setup)
filter(event => includeRules.length > 0
? includeRules.some(rule => rule.test(event.urlAfterRedirects))
: true), filter(event => excludeRules.length > 0
? !excludeRules.some(rule => rule.test(event.urlAfterRedirects))
: true))
.subscribe(event => gaService.pageView(event.urlAfterRedirects, undefined));
// Cleanup
c.onDestroy(() => subs.unsubscribe());
};
}
/** Converts all path rules from string to Regex instances */
function normalizePathRules(rules) {
return rules.map(rule => (rule instanceof RegExp)
? rule
: new RegExp(`^${rule.replace('*', '.*')}$`, 'i'));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29vZ2xlLWFuYWx5dGljcy1yb3V0ZXIuaW5pdGlhbGl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZ29vZ2xlLWFuYWx5dGljcy9zcmMvbGliL2luaXRpYWxpemVycy9nb29nbGUtYW5hbHl0aWNzLXJvdXRlci5pbml0aWFsaXplci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsc0JBQXNCLEVBQXlCLE1BQU0sZUFBZSxDQUFDO0FBQzdFLE9BQU8sRUFBUSxhQUFhLEVBQUUsTUFBTSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDN0QsT0FBTyxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFbEMsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFDNUUsT0FBTyxFQUFDLDJDQUEyQyxFQUFDLE1BQU0sc0RBQXNELENBQUM7QUFFakg7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxnREFBZ0QsR0FBYTtJQUN0RSxPQUFPLEVBQUUsc0JBQXNCO0lBQy9CLEtBQUssRUFBRSxJQUFJO0lBQ1gsVUFBVSxFQUFFLGdDQUFnQztJQUM1QyxJQUFJLEVBQUU7UUFDRiwyQ0FBMkM7UUFDM0Msc0JBQXNCO0tBQ3pCO0NBQ0osQ0FBQztBQUVGOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLFVBQVUsZ0NBQWdDLENBQzVDLFFBQXlDLEVBQ3pDLFNBQWlDO0lBRWpDLE9BQU8sQ0FBQyxDQUF3QixFQUFFLEVBQUU7UUFDaEMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEMsTUFBTSxFQUFDLE9BQU8sR0FBRyxFQUFFLEVBQUUsT0FBTyxHQUFHLEVBQUUsRUFBQyxHQUFHLFFBQVEsSUFBSSxFQUFFLENBQUM7UUFDcEQsTUFBTSxZQUFZLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakQsTUFBTSxZQUFZLEdBQUcsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakQsTUFBTSxJQUFJLEdBQUcsTUFBTTthQUNkLE1BQU07YUFDTixJQUFJLENBQ0QsTUFBTSxDQUFDLENBQUMsS0FBWSxFQUEwQixFQUFFLENBQUMsS0FBSyxZQUFZLGFBQWEsQ0FBQyxFQUNoRixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsd0ZBQXdGO1FBQ2pHLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUNuQyxDQUFDLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDL0QsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUNYLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUNuQyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUNoRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQ2Q7YUFDQSxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ2hGLFVBQVU7UUFDVixDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLENBQUMsQ0FBQztBQUNOLENBQUM7QUFFRCw2REFBNkQ7QUFDN0QsU0FBUyxrQkFBa0IsQ0FBQyxLQUE2QjtJQUNyRCxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksWUFBWSxNQUFNLENBQUM7UUFDN0MsQ0FBQyxDQUFDLElBQUk7UUFDTixDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDM0QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QVBQX0JPT1RTVFJBUF9MSVNURU5FUiwgQ29tcG9uZW50UmVmLCBQcm92aWRlcn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7RXZlbnQsIE5hdmlnYXRpb25FbmQsIFJvdXRlcn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHtmaWx0ZXIsIHNraXB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQge0lHb29nbGVBbmFseXRpY3NSb3V0aW5nU2V0dGluZ3N9IGZyb20gJy4uL2ludGVyZmFjZXMvaS1nb29nbGUtYW5hbHl0aWNzLXJvdXRpbmctc2V0dGluZ3MnO1xyXG5pbXBvcnQge0dvb2dsZUFuYWx5dGljc1NlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2VzL2dvb2dsZS1hbmFseXRpY3Muc2VydmljZSc7XHJcbmltcG9ydCB7TkdYX0dPT0dMRV9BTkFMWVRJQ1NfUk9VVElOR19TRVRUSU5HU19UT0tFTn0gZnJvbSAnLi4vdG9rZW5zL25neC1nb29nbGUtYW5hbHl0aWNzLXJvdXRlci1zZXR0aW5ncy10b2tlbic7XHJcblxyXG4vKipcclxuICogUHJvdmlkZSBhIERJIENvbmZpZ3VyYXRpb24gdG8gYXR0YWNoIEdBIFRyaWdnZXIgdG8gUm91dGVyIEV2ZW50cyBhdCBBbmd1bGFyIFN0YXJ0dXAgQ3ljbGUuXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgTkdYX0dPT0dMRV9BTkFMWVRJQ1NfUk9VVEVSX0lOSVRJQUxJWkVSX1BST1ZJREVSOiBQcm92aWRlciA9IHtcclxuICAgIHByb3ZpZGU6IEFQUF9CT09UU1RSQVBfTElTVEVORVIsXHJcbiAgICBtdWx0aTogdHJ1ZSxcclxuICAgIHVzZUZhY3Rvcnk6IEdvb2dsZUFuYWx5dGljc1JvdXRlckluaXRpYWxpemVyLFxyXG4gICAgZGVwczogW1xyXG4gICAgICAgIE5HWF9HT09HTEVfQU5BTFlUSUNTX1JPVVRJTkdfU0VUVElOR1NfVE9LRU4sXHJcbiAgICAgICAgR29vZ2xlQW5hbHl0aWNzU2VydmljZVxyXG4gICAgXVxyXG59O1xyXG5cclxuLyoqXHJcbiAqIEF0dGFjaCBhIGxpc3RlbmVyIHRvIGBOYXZpZ2F0aW9uRW5kYCBSb3V0ZXIgZXZlbnQuIFNvLCBldmVyeSB0aW1lIFJvdXRlciBmaW5pc2ggdGhlIHBhZ2UgcmVzb2x1dGlvbiBpdCBzaG91bGQgY2FsbCBgTmF2aWdhdGlvbkVuZGAgZXZlbnQuXHJcbiAqIFdlIGFzc3VtZSB0aGF0IE5hdmlnYXRpb25FbmQgaXMgdGhlIGZpbmFsIHBhZ2UgcmVzb2x1dGlvbiBhbmQgY2FsbCBHQSBgcGFnZV92aWV3YCBjb21tYW5kLlxyXG4gKlxyXG4gKiBUbyBhdm9pZCBkb3VibGUgYmluZHMsIHdlIGFsc28gZGVzdHJveSB0aGUgc3Vic2NyaXB0aW9uIHdoZW4gZGUgQm9vdHN0cmFwIENvbXBvbmVudCBpcyBkZXN0cm95ZWQuIEJ1dCwgd2UgZG9uJ3Qga25vdyBmb3Igc3VyZVxyXG4gKiB0aGF0IHRoaXMgc3RyYXRlZ3kgZG9lcyBub3QgY2F1c2UgZG91YmxlIGJpbmQgb24gbXVsdGlwbGUgYm9vdHN0cmFwIGNvbXBvbmVudHMuXHJcbiAqXHJcbiAqIFdlIGFyZSB1c2luZyB0aGUgY29tcG9uZW50J3MgaW5qZWN0b3IgcmVmZXJlbmNlIHRvIHJlc29sdmUgUm91dGVyLCBzbyBJIGhvcGUgdGhlcmUgaXMgbm8gcHJvYmxlbSB3aXRoIGRvdWJsZSBiaW5kaW5nLlxyXG4gKlxyXG4gKiBJZiB5b3UgaGF2ZSB0aGlzIHByb2JsZW0sIEkgZW5jb3VyYWdlIG5vdCBVc2UgTmd4R29vZ2xlQW5hbHl0aWNzUm91dGVyTW9kdWxlIGFuZCBhdHRhY2ggdGhlIGxpc3RlbmVyIG9uIEFwcENvbXBvbmVudCBpbml0aWFsaXphdGlvbi5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHb29nbGVBbmFseXRpY3NSb3V0ZXJJbml0aWFsaXplcihcclxuICAgIHNldHRpbmdzOiBJR29vZ2xlQW5hbHl0aWNzUm91dGluZ1NldHRpbmdzLFxyXG4gICAgZ2FTZXJ2aWNlOiBHb29nbGVBbmFseXRpY3NTZXJ2aWNlXHJcbikge1xyXG4gICAgcmV0dXJuIChjOiBDb21wb25lbnRSZWY8dW5rbm93bj4pID0+IHtcclxuICAgICAgICBjb25zdCByb3V0ZXIgPSBjLmluamVjdG9yLmdldChSb3V0ZXIpO1xyXG4gICAgICAgIGNvbnN0IHtpbmNsdWRlID0gW10sIGV4Y2x1ZGUgPSBbXX0gPSBzZXR0aW5ncyA/PyB7fTtcclxuICAgICAgICBjb25zdCBpbmNsdWRlUnVsZXMgPSBub3JtYWxpemVQYXRoUnVsZXMoaW5jbHVkZSk7XHJcbiAgICAgICAgY29uc3QgZXhjbHVkZVJ1bGVzID0gbm9ybWFsaXplUGF0aFJ1bGVzKGV4Y2x1ZGUpO1xyXG4gICAgICAgIGNvbnN0IHN1YnMgPSByb3V0ZXJcclxuICAgICAgICAgICAgLmV2ZW50c1xyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgIGZpbHRlcigoZXZlbnQ6IEV2ZW50KTogZXZlbnQgaXMgTmF2aWdhdGlvbkVuZCA9PiBldmVudCBpbnN0YW5jZW9mIE5hdmlnYXRpb25FbmQpLFxyXG4gICAgICAgICAgICAgICAgc2tpcCgxKSwgLy8gUHJldmVudCBkb3VibGUgdmlld3Mgb24gdGhlIGZpcnN0IHRyaWdnZXIgKGJlY2F1c2UgR0EgQWxyZWFkeSBzZW5kIG9uZSBwaW5nIG9uIHNldHVwKVxyXG4gICAgICAgICAgICAgICAgZmlsdGVyKGV2ZW50ID0+IGluY2x1ZGVSdWxlcy5sZW5ndGggPiAwXHJcbiAgICAgICAgICAgICAgICAgICAgPyBpbmNsdWRlUnVsZXMuc29tZShydWxlID0+IHJ1bGUudGVzdChldmVudC51cmxBZnRlclJlZGlyZWN0cykpXHJcbiAgICAgICAgICAgICAgICAgICAgOiB0cnVlKSxcclxuICAgICAgICAgICAgICAgIGZpbHRlcihldmVudCA9PiBleGNsdWRlUnVsZXMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAgICAgICAgID8gIWV4Y2x1ZGVSdWxlcy5zb21lKHJ1bGUgPT4gcnVsZS50ZXN0KGV2ZW50LnVybEFmdGVyUmVkaXJlY3RzKSlcclxuICAgICAgICAgICAgICAgICAgICA6IHRydWUpXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICAgICAgLnN1YnNjcmliZShldmVudCA9PiBnYVNlcnZpY2UucGFnZVZpZXcoZXZlbnQudXJsQWZ0ZXJSZWRpcmVjdHMsIHVuZGVmaW5lZCkpO1xyXG4gICAgICAgIC8vIENsZWFudXBcclxuICAgICAgICBjLm9uRGVzdHJveSgoKSA9PiBzdWJzLnVuc3Vic2NyaWJlKCkpO1xyXG4gICAgfTtcclxufVxyXG5cclxuLyoqIENvbnZlcnRzIGFsbCBwYXRoIHJ1bGVzIGZyb20gc3RyaW5nIHRvIFJlZ2V4IGluc3RhbmNlcyAqL1xyXG5mdW5jdGlvbiBub3JtYWxpemVQYXRoUnVsZXMocnVsZXM6IEFycmF5PHN0cmluZyB8IFJlZ0V4cD4pOiBBcnJheTxSZWdFeHA+IHtcclxuICAgIHJldHVybiBydWxlcy5tYXAocnVsZSA9PiAocnVsZSBpbnN0YW5jZW9mIFJlZ0V4cClcclxuICAgICAgICA/IHJ1bGVcclxuICAgICAgICA6IG5ldyBSZWdFeHAoYF4ke3J1bGUucmVwbGFjZSgnKicsICcuKicpfSRgLCAnaScpKTtcclxufVxyXG4iXX0=