| 27 | * - Data is uploaded to our main Google Analytics 4+ property. |
| 28 | */ |
| 29 | export class AnalyticsService { |
| 30 | private environment = inject(ENVIRONMENT); |
| 31 | private window: WindowWithAnalytics = inject(WINDOW); |
| 32 | private readonly localStorage = inject(LOCAL_STORAGE); |
| 33 | private isBrowser = isPlatformBrowser(inject(PLATFORM_ID)); |
| 34 | |
| 35 | constructor() { |
| 36 | if (this.isBrowser) { |
| 37 | this._installGlobalSiteTag(); |
| 38 | this._installWindowErrorHandler(); |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | reportError(description: string, fatal = true) { |
| 43 | // Limit descriptions to maximum of 150 characters. |
| 44 | // See: https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#exd. |
| 45 | description = description.substring(0, 150); |
| 46 | |
| 47 | this._gtag('event', 'exception', {description, fatal}); |
| 48 | } |
| 49 | |
| 50 | sendEvent(name: string, parameters: Record<string, string | boolean | number>) { |
| 51 | this._gtag('event', name, parameters); |
| 52 | } |
| 53 | |
| 54 | private _gtag(...args: any[]) { |
| 55 | if (this.window.gtag) { |
| 56 | this.window.gtag(...args); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | private _installGlobalSiteTag() { |
| 61 | const window = this.window; |
| 62 | const url = `https://www.googletagmanager.com/gtag/js?id=${this.environment.googleAnalyticsId}`; |
| 63 | |
| 64 | // Note: This cannot be an arrow function as `gtag.js` expects an actual `Arguments` |
| 65 | // instance with e.g. `callee` to be set. Do not attempt to change this and keep this |
| 66 | // as much as possible in sync with the tracking code snippet suggested by the Google |
| 67 | // Analytics 4 web UI under `Data Streams`. |
| 68 | window.dataLayer = this.window.dataLayer || []; |
| 69 | window.gtag = function () { |
| 70 | window.dataLayer?.push(arguments); |
| 71 | }; |
| 72 | |
| 73 | // Cookie banner consent initial state |
| 74 | // This code is modified in the @angular/docs package in the cookie-popup component. |
| 75 | // Docs: https://developers.google.com/tag-platform/security/guides/consent |
| 76 | if (this.localStorage) { |
| 77 | if (this.localStorage.getItem(STORAGE_KEY) === 'true') { |
| 78 | setCookieConsent('granted'); |
| 79 | } else { |
| 80 | setCookieConsent('denied'); |
| 81 | } |
| 82 | } else { |
| 83 | // In case localStorage is not available, we default to denying cookies. |
| 84 | setCookieConsent('denied'); |
| 85 | } |
| 86 |
nothing calls this directly
no test coverage detected
searching dependent graphs…