ngx-matomo
Version:
Matomo (aka. Piwik) web analytics for Angular applications.
100 lines • 14 kB
JavaScript
import { Injectable, Inject } from '@angular/core';
import { NavigationEnd, NavigationStart } from '@angular/router';
import { filter, map, pairwise } from 'rxjs/operators';
import { isNonNull } from '../helpers';
import { MATOMO_CONFIGURATION } from './matomo-configuration';
import * as i0 from "@angular/core";
import * as i1 from "./matomo-tracker.service";
import * as i2 from "@angular/router";
/**
* Service for tracking route changes.
*
* @export
*/
export class MatomoRouteTracker {
/**
* Creates an instance of MatomoRouteTracker.
*
* @param configuration Matomo configuration provided by DI.
* @param matomoTracker Instance of MatomoTracker provided by DI.
* @param router Instance of Router provided by DI.
* @param activatedRoute Instance of ActivatedRoute provided by DI.
*/
constructor(configuration, matomoTracker, router, activatedRoute) {
this.configuration = configuration;
this.matomoTracker = matomoTracker;
this.router = router;
this.activatedRoute = activatedRoute;
}
/**
* Starts tracking route changes.
* Matomo DocumentTitle will be set with `data.matomoTitle` of your routes.
*
* This service shall not be used directly within an application.
*/
startTracking() {
this.subscription = this.router.events
.pipe(filter((event) => event instanceof NavigationStart || event instanceof NavigationEnd), map((event) => ({ timestamp: new Date().getTime(), event })), pairwise(), filter(([a, b]) => a.event instanceof NavigationStart && b.event instanceof NavigationEnd))
.subscribe({
next: ([start, end]) => {
let currentRoute = this.activatedRoute.root;
while (currentRoute.children[0] !== undefined) {
currentRoute = currentRoute.children[0];
}
// Set referrer if it exists
if (this.previousPageUrl) {
this.matomoTracker.setReferrerUrl(this.previousPageUrl);
}
// Track current page
if (!!currentRoute.snapshot.data['matomoTitle']) {
this.matomoTracker.setDocumentTitle(currentRoute.snapshot.data['matomoTitle']);
}
this.matomoTracker.setCustomUrl(window.location.href);
// Remove all previously assigned custom variables
// (requires Matomo (formerly Piwik) 3.0.2+)
this.matomoTracker.deleteCustomVariables('page');
this.matomoTracker.setGenerationTimeMs(end.timestamp - start.timestamp);
this.matomoTracker.trackPageView();
// Set previous route URL
this.previousPageUrl = window.location.href;
// Make Matomo aware of newly added content
this.configuration?.routeTracking?.contentIds
?.map(document.getElementById)
?.filter(isNonNull)
?.forEach((content) => {
// TODO To be implemented when Media Analytics will be supported.
// this.matomoTracker.scanForMedia(content);
// TODO To be implemented when Form Analytics will be supported.
// this.matomoTracker.scanForForms(content);
this.matomoTracker.trackContentImpressionsWithinNode(content);
});
if (this.configuration.trackLinks === true) {
this.matomoTracker.enableLinkTracking(this.configuration.trackLinkValue);
}
},
});
}
/**
* Stops tracking route changes.
*/
stopTracking() {
this.subscription?.unsubscribe();
}
/**
* Angular OnDestroy lifecycle hook.
*/
ngOnDestroy() {
if (!!this.subscription) {
this.subscription.unsubscribe();
}
}
}
MatomoRouteTracker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: MatomoRouteTracker, deps: [{ token: MATOMO_CONFIGURATION }, { token: i1.MatomoTracker }, { token: i2.Router }, { token: i2.ActivatedRoute }], target: i0.ɵɵFactoryTarget.Injectable });
MatomoRouteTracker.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: MatomoRouteTracker });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: MatomoRouteTracker, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [MATOMO_CONFIGURATION]
}] }, { type: i1.MatomoTracker }, { type: i2.Router }, { type: i2.ActivatedRoute }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0b21vLXJvdXRlLXRyYWNrZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1tYXRvbW8vc3JjL2xpYi9tYXRvbW8tcm91dGUtdHJhY2tlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQzlELE9BQU8sRUFBa0IsYUFBYSxFQUFFLGVBQWUsRUFBVSxNQUFNLGlCQUFpQixDQUFDO0FBR3pGLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXZELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdkMsT0FBTyxFQUF1QixvQkFBb0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDOzs7O0FBR25GOzs7O0dBSUc7QUFFSCxNQUFNLE9BQU8sa0JBQWtCO0lBVTdCOzs7Ozs7O09BT0c7SUFDSCxZQUNpRCxhQUFrQyxFQUNoRSxhQUE0QixFQUM1QixNQUFjLEVBQ2QsY0FBOEI7UUFIQSxrQkFBYSxHQUFiLGFBQWEsQ0FBcUI7UUFDaEUsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtJQUM5QyxDQUFDO0lBRUo7Ozs7O09BS0c7SUFDSCxhQUFhO1FBQ1gsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU07YUFDbkMsSUFBSSxDQUNILE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxZQUFZLGVBQWUsSUFBSSxLQUFLLFlBQVksYUFBYSxDQUFDLEVBQ3JGLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxD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QUFNOzJCQUFDLG9CQUFvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIEluamVjdCwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgTmF2aWdhdGlvbkVuZCwgTmF2aWdhdGlvblN0YXJ0LCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgbWFwLCBwYWlyd2lzZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgaXNOb25OdWxsIH0gZnJvbSAnLi4vaGVscGVycyc7XG5pbXBvcnQgeyBNYXRvbW9Db25maWd1cmF0aW9uLCBNQVRPTU9fQ09ORklHVVJBVElPTiB9IGZyb20gJy4vbWF0b21vLWNvbmZpZ3VyYXRpb24nO1xuaW1wb3J0IHsgTWF0b21vVHJhY2tlciB9IGZyb20gJy4vbWF0b21vLXRyYWNrZXIuc2VydmljZSc7XG5cbi8qKlxuICogU2VydmljZSBmb3IgdHJhY2tpbmcgcm91dGUgY2hhbmdlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBNYXRvbW9Sb3V0ZVRyYWNrZXIgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogUHJldmlvdXMgcm91dGUgdXJsIG9mIG1hdG9tbyByb3V0ZSB0cmFja2VyLlxuICAgKi9cbiAgcHJpdmF0ZSBwcmV2aW91c1BhZ2VVcmw/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTdWJzY3JpcHRpb24gZm9yIG1hbmFnaW5nIHJvdXRlIGV2ZW50cy5cbiAgICovXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIE1hdG9tb1JvdXRlVHJhY2tlci5cbiAgICpcbiAgICogQHBhcmFtIGNvbmZpZ3VyYXRpb24gTWF0b21vIGNvbmZpZ3VyYXRpb24gcHJvdmlkZWQgYnkgREkuXG4gICAqIEBwYXJhbSBtYXRvbW9UcmFja2VyIEluc3RhbmNlIG9mIE1hdG9tb1RyYWNrZXIgcHJvdmlkZWQgYnkgREkuXG4gICAqIEBwYXJhbSByb3V0ZXIgSW5zdGFuY2Ugb2YgUm91dGVyIHByb3ZpZGVkIGJ5IERJLlxuICAgKiBAcGFyYW0gYWN0aXZhdGVkUm91dGUgSW5zdGFuY2Ugb2YgQWN0aXZhdGVkUm91dGUgcHJvdmlkZWQgYnkgREkuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KE1BVE9NT19DT05GSUdVUkFUSU9OKSBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZ3VyYXRpb246IE1hdG9tb0NvbmZpZ3VyYXRpb24sXG4gICAgcHJpdmF0ZSByZWFkb25seSBtYXRvbW9UcmFja2VyOiBNYXRvbW9UcmFja2VyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyOiBSb3V0ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBhY3RpdmF0ZWRSb3V0ZTogQWN0aXZhdGVkUm91dGVcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBTdGFydHMgdHJhY2tpbmcgcm91dGUgY2hhbmdlcy5cbiAgICogTWF0b21vIERvY3VtZW50VGl0bGUgd2lsbCBiZSBzZXQgd2l0aCBgZGF0YS5tYXRvbW9UaXRsZWAgb2YgeW91ciByb3V0ZXMuXG4gICAqXG4gICAqIFRoaXMgc2VydmljZSBzaGFsbCBub3QgYmUgdXNlZCBkaXJlY3RseSB3aXRoaW4gYW4gYXBwbGljYXRpb24uXG4gICAqL1xuICBzdGFydFRyYWNraW5nKCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5yb3V0ZXIuZXZlbnRzXG4gICAgICAucGlwZShcbiAgICAgICAgZmlsdGVyKChldmVudCkgPT4gZXZlbnQgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uU3RhcnQgfHwgZXZlbnQgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRW5kKSxcbiAgICAgICAgbWFwKChldmVudCkgPT4gKHsgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLmdldFRpbWUoKSwgZXZlbnQgfSkpLFxuICAgICAgICBwYWlyd2lzZSgpLFxuICAgICAgICBmaWx0ZXIoKFthLCBiXSkgPT4gYS5ldmVudCBpbnN0YW5jZW9mIE5hdmlnYXRpb25TdGFydCAmJiBiLmV2ZW50IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoW3N0YXJ0LCBlbmRdKSA9PiB7XG4gICAgICAgICAgbGV0IGN1cnJlbnRSb3V0ZSA9IHRoaXMuYWN0aXZhdGVkUm91dGUucm9vdDtcbiAgICAgICAgICB3aGlsZSAoY3VycmVudFJvdXRlLmNoaWxkcmVuWzBdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGN1cnJlbnRSb3V0ZSA9IGN1cnJlbnRSb3V0ZS5jaGlsZHJlblswXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gU2V0IHJlZmVycmVyIGlmIGl0IGV4aXN0c1xuICAgICAgICAgIGlmICh0aGlzLnByZXZpb3VzUGFnZVVybCkge1xuICAgICAgICAgICAgdGhpcy5tYXRvbW9UcmFja2VyLnNldFJlZmVycmVyVXJsKHRoaXMucHJldmlvdXNQYWdlVXJsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVHJhY2sgY3VycmVudCBwYWdlXG4gICAgICAgICAgaWYgKCEhY3VycmVudFJvdXRlLnNuYXBzaG90LmRhdGFbJ21hdG9tb1RpdGxlJ10pIHtcbiAgICAgICAgICAgIHRoaXMubWF0b21vVHJhY2tlci5zZXREb2N1bWVudFRpdGxlKGN1cnJlbnRSb3V0ZS5zbmFwc2hvdC5kYXRhWydtYXRvbW9UaXRsZSddKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5tYXRvbW9UcmFja2VyLnNldEN1c3RvbVVybCh3aW5kb3cubG9jYXRpb24uaHJlZik7XG4gICAgICAgICAgLy8gUmVtb3ZlIGFsbCBwcmV2aW91c2x5IGFzc2lnbmVkIGN1c3RvbSB2YXJpYWJsZXNcbiAgICAgICAgICAvLyAocmVxdWlyZXMgTWF0b21vIChmb3JtZXJseSBQaXdpaykgMy4wLjIrKVxuICAgICAgICAgIHRoaXMubWF0b21vVHJhY2tlci5kZWxldGVDdXN0b21WYXJpYWJsZXMoJ3BhZ2UnKTtcbiAgICAgICAgICB0aGlzLm1hdG9tb1RyYWNrZXIuc2V0R2VuZXJhdGlvblRpbWVNcyhlbmQudGltZXN0YW1wIC0gc3RhcnQudGltZXN0YW1wKTtcbiAgICAgICAgICB0aGlzLm1hdG9tb1RyYWNrZXIudHJhY2tQYWdlVmlldygpO1xuICAgICAgICAgIC8vIFNldCBwcmV2aW91cyByb3V0ZSBVUkxcbiAgICAgICAgICB0aGlzLnByZXZpb3VzUGFnZVVybCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuXG4gICAgICAgICAgLy8gTWFrZSBNYXRvbW8gYXdhcmUgb2YgbmV3bHkgYWRkZWQgY29udGVudFxuICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbj8ucm91dGVUcmFja2luZz8uY29udGVudElkc1xuICAgICAgICAgICAgPy5tYXAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQpXG4gICAgICAgICAgICA/LmZpbHRlcihpc05vbk51bGwpXG4gICAgICAgICAgICA/LmZvckVhY2goKGNvbnRlbnQpID0+IHtcbiAgICAgICAgICAgICAgLy8gVE9ETyBUbyBiZSBpbXBsZW1lbnRlZCB3aGVuIE1lZGlhIEFuYWx5dGljcyB3aWxsIGJlIHN1cHBvcnRlZC5cbiAgICAgICAgICAgICAgLy8gdGhpcy5tYXRvbW9UcmFja2VyLnNjYW5Gb3JNZWRpYShjb250ZW50KTtcbiAgICAgICAgICAgICAgLy8gVE9ETyBUbyBiZSBpbXBsZW1lbnRlZCB3aGVuIEZvcm0gQW5hbHl0aWNzIHdpbGwgYmUgc3VwcG9ydGVkLlxuICAgICAgICAgICAgICAvLyB0aGlzLm1hdG9tb1RyYWNrZXIuc2NhbkZvckZvcm1zKGNvbnRlbnQpO1xuICAgICAgICAgICAgICB0aGlzLm1hdG9tb1RyYWNrZXIudHJhY2tDb250ZW50SW1wcmVzc2lvbnNXaXRoaW5Ob2RlKGNvbnRlbnQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uLnRyYWNrTGlua3MgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHRoaXMubWF0b21vVHJhY2tlci5lbmFibGVMaW5rVHJhY2tpbmcodGhpcy5jb25maWd1cmF0aW9uLnRyYWNrTGlua1ZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wcyB0cmFja2luZyByb3V0ZSBjaGFuZ2VzLlxuICAgKi9cbiAgc3RvcFRyYWNraW5nKCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFuZ3VsYXIgT25EZXN0cm95IGxpZmVjeWNsZSBob29rLlxuICAgKi9cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKCEhdGhpcy5zdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG59XG4iXX0=