angulartics2
angulartics2 copied to clipboard
Piwik does not track external Links or Downloads
-
I'm submitting a ... [x] bug report [ ] feature request [ ] question about the decisions made in the repository
-
Do you want to request a feature or report a bug?
Report a bug.
- What is the current behavior?
external Links and Downloads are not tracked with Piwik. Piwik tracks external Links and Downloads by adding Click Listeners to the links. This happens on piwik initialisation. If now the DOM changes with new external Links and Downloads, Piwik needs to reanalyse the page. But this gets not triggered by angulartics.
Trigger Piwik is possible with _paq.push(['enableLinkTracking']);
. Since 3.0.2 it is possible to call this several times.
I added _paq.push(['enableLinkTracking']);
here to enable link tracking:
https://github.com/angulartics/angulartics2/blob/master/src/providers/piwik/angulartics2-piwik.ts#L31
Problem is angulartics triggers this by listening to the NavigationEnd, but this events gets fired directly after the navigation, where the new component is not loaded yet. So the DOM changes are after the Piwik trigger to reanalyse.
As a quick workaround it put this code: https://github.com/angulartics/angulartics2/blob/master/src/providers/piwik/angulartics2-piwik.ts#L28-L36
in a setTimeout(function(){...},200);
block, and it works.
But the setTimeout() workaround is not nice i think and also it only covers DOM changes on a router event. But there are several other cases where external Links or downloads could be added to the DOM without a router event. (loading sub-components by Dropdown, etc..)
- If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem
see above
- What is the expected behavior?
external Links and Downloads should be tracked by piwik
- What is the motivation / use case for changing the behavior?
tracking external Links and Downloads
- Please tell us about your environment:
- Angular version: 4.0.1
- Browser: all
- Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)
see current behaviour
related issue could be #112. There the issue is a race condition for using the same NavigationEnd to trigger Piwik and update the title. As the problem here is that DOM changes happen after the NavigationEnd Method the solution could be the same for both issues. But I still think these are separate issues.
I build a quick workaround to make piwik aware of new links.
Just a Directive calling _paq.push(['enableLinkTracking']);
for all created links.
(From performance view this looks bad, but i only have a few external links and Downloads so it should work as a workaround)
import { AfterViewInit, Directive, ElementRef } from '@angular/core';
declare let _paq: any;
@Directive({
selector: 'a'
})
export class LinkDirective implements AfterViewInit {
constructor(private el: ElementRef) {
}
// wait until hrefs are final rendered, href may is empty on ngOnInit()
ngAfterViewInit() {
// we only need to track external links
// to track downloads perhaps also internal links are needed
if (this.el.nativeElement.host !== window.location.host) {
_paq.push(['enableLinkTracking']);
}
}
}
Here is my workaround: I created a directive that detect changes to anchor's href attribute. This is more efficient as you can apply it to any element and it only detects changes to sub-elements.
import { Directive, ElementRef, OnDestroy } from '@angular/core';
declare let _paq: any;
@Directive({
selector: '[linkChange]',
})
export class LinkChangeDirective implements OnDestroy {
private changes: MutationObserver;
constructor(private el: ElementRef) {
const element = this.el.nativeElement;
this.changes = new MutationObserver((mutations: MutationRecord[]) => {
mutations.forEach((mutation: MutationRecord) => this.enableLinkTracking(mutation.target));
});
this.changes.observe(element, {
attributes: true,
subtree: true,
attributeFilter: ['href'],
});
}
private enableLinkTracking(anchor: any): void {
if (anchor.host !== window.location.host) {
_paq.push(['enableLinkTracking']);
}
}
ngOnDestroy(): void {
this.changes.disconnect();
}
}