Подтвердить что ты не робот

Отслеживание просмотров страниц Google Analytics в Angular2

Я построил новый сайт, используя Angular 2 в качестве front-end. Поскольку все выполняется с помощью состояния push, нет загрузок страниц, которые обычно запускают код Google Analytics для отправки просмотра страницы на серверы Google.

Как я могу вручную отправлять события просмотра страницы в Google, чтобы я мог отслеживать, что просматривают пользователи моего сайта?

4b9b3361

Ответ 1

Мне удалось получить эту работу, подписавшись на изменения на маршрутизаторе, проверяя, что маршрут фактически изменился (я периодически получал несколько событий на некоторых маршрутах), а затем отправлял новый путь в Google.

app.component.ts

import { ... } from '...';

// Declare ga function as ambient
declare var ga:Function;

@Component({ ... })

export class AppComponent {
    private currentRoute:string;

    constructor(_router:Router) {
        // Using Rx built in `distinctUntilChanged ` feature to handle url change c/o @dloomb answer
        router.events.distinctUntilChanged((previous: any, current: any) => {
            // Subscribe to any `NavigationEnd` events where the url has changed
            if(current instanceof NavigationEnd) {
                return previous.url === current.url;
            }
            return true;
        }).subscribe((x: any) => {
            ga('set', 'page', x.url);
            ga('send', 'pageview')
        });
      }
    }
}

Вам также необходимо включить код аналитики google в основной файл индекса перед загрузкой вашего приложения angular2, чтобы глобальный объект ga существовал, но вы не хотите отправлять начальное представление дважды. Чтобы сделать это, удалите следующую строку из GA script

index.html

<script>
  (function(i,s,o,g,r,a,m){...})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-XXXXXXXX-X', 'auto');
  // Remove this line to avoid sending the first page view twice.
  //ga('send', 'pageview');

</script>
<!-- 
    Load your ng2 app after ga. 
    This style of deferred script loading doesn't guarantee this will happen
    but you can use Promise or what works for your particular project. 
-->
<script defer type="text/javascript" src="/app.js"></script>

Использование сторонней библиотеки

В качестве альтернативы реализации GA самостоятельно, библиотека Angulartics2 также является популярным инструментом для реализации отслеживания GA, а также интегрируется с другими аналитиками поставщиков.

Ответ 2

Развернувшись на ответ Яна. Вы можете использовать встроенные функции Rx для обработки различий между текущими и новыми маршрутами.

import { NavigationEnd, Router } from '@angular/router';

declare var ga: any;

export class AppComponent {
        constructor(public router: Router) {
            router.events.distinctUntilChanged((previous: any, current: any) => {
                if(current instanceof NavigationEnd) {
                    return previous.url === current.url;
                }
                return true;
            }).subscribe((x: any) => {
                console.log('router.change', x);
                ga('send', 'pageview', x.url);
            });
        }
    }

Мы используем оператор distinctUntilChanged, чтобы заставить наблюдателя испускать только те элементы, которые имеют тип NavigationEnd, и не имеют того же маршрута, что и ранее выпущенный элемент.

Ответ 3

Если вы столкнулись с этой проблемой после августа 2017 года, вам, скорее всего, следует использовать gtag.js (глобальный тег сайта Google Analytics) вместо старого analytics.js. Я предлагаю вам проверить разницу между обоими в Migrate от analytics.js на страницу gtag.js, а также как gtag.js работает в одностраничных приложениях, прежде чем продолжить.

Когда вы получаете свой фрагмент кода из Google Analytics, он выглядит следующим образом:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= GOOGLE_ANALYTICS_ID %>"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', '<%= GOOGLE_ANALYTICS_ID %>'); <!-- Remove that one -->
</script>

Вам нужно удалить последнюю строку скрипта и добавить остальные в ваш index.html.

Затем вам нужно добавить строку, которую вы удалили из сценария выше, в свой код и добавить страницу для отслеживания. По сути, это почти то же самое, что парни выше предложили для analytics.js но теперь вы используете функцию gtag.js

Например, если вы хотите отслеживать все страницы, которые вы открываете, вот пример кода:

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import 'rxjs/add/operator/distinctUntilChanged';

// This still has to be declared
declare var gtag: Function;

@Component({
    moduleId: module.id,
    selector: 'my-app',
    templateUrl: 'app.component.html',
    styleUrls: ['app.component.css'],
})
export class AppComponent implements OnInit {

    constructor(private router: Router) { }

    ngOnInit() {
        this.router.events.distinctUntilChanged((previous: any, current: any) => {
            // Subscribe to any 'NavigationEnd' events where the url has changed
            if(current instanceof NavigationEnd) {
                return previous.url === current.url;
            }
            return true;
        }).subscribe((x: any) => {
            gtag('config', '<%= GOOGLE_ANALYTICS_ID %>', {'page_path': x.url});
        });
    }
}

Если вы прочитали документацию по gtag.js то знаете, что может быть множество вариантов отслеживания, но я gtag.js на самом gtag.js использовании.

Ответ 4

В Angular 6 я предлагаю для app.component.ts:

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router'
import { Title } from '@angular/platform-browser';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

  constructor(
    private router: Router,
    private titleService: Title
  ){ }

  ngOnInit() {
     this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        (<any>window).gtag('config', '<%= GOOGLE_ANALYTICS_ID %>', {
          'page_title' : this.titleService.getTitle(),
          'page_path': event.urlAfterRedirects
        });
      }
    });
  }

}

Для index.html:

  <!-- Global site tag (gtag.js) - Google Analytics -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=<%= GOOGLE_ANALYTICS_ID %>"></script>
  <script>
    window.dataLayer = window.dataLayer || [];
    function gtag() { dataLayer.push(arguments); }
    gtag('js', new Date());
  </script>

Вы можете управлять заголовком своих страниц с помощью службы Заголовок, предоставляемой Angular: https://angular.io/guide/set-document-title

Ответ 5

Предполагая, что каждый угловой маршрут имеет свой собственный заголовок в app.routing.ts:

   {
    path: 'shop',
    component: ShopComponent,
    data: {
      title: ' == This is Shop Component Title =='
    },
    canActivate: [AuthGuard]
  },

Ранее упомянутые решения будут по-прежнему отображать один и тот же заголовок страницы для каждого маршрута в отчете Google Analytics. Чтобы использовать соответствующие заголовки Angular Route (вместо содержимого тега index.html <title> все время), используйте код ниже в app.component.ts

  this.router.events.subscribe(event => {

  if (event instanceof NavigationEnd) {
    (<any>window).ga('set', 'page', event.urlAfterRedirects);

    // ----------
    //use the following 3 lines of code to use
    //correnct titles for routes        
    // ----------

    let currentRoute = this.route.root;
    let title = this.getPageTitle(currentRoute);
    (<any>window).ga('set', 'title', title);

    (<any>window).ga('send', 'pageview');

  }
});

... где метод getPageTitle выглядит следующим образом:

getPageTitle = function (currentRoute: ActivatedRoute) {
  let data;
    do {
      const childrenRoutes = currentRoute.children;
      currentRoute = null;
      childrenRoutes.forEach(route => {

      if (route.outlet === 'primary') {
        currentRoute = route;
        data = route.snapshot.data;
      }
    });
  } while (currentRoute);
  return data.title;
};

Примечание: это решение относится к Anguler 5 и ниже. В Angular 6 вы также можете использовать TitleService

Ответ 6

this.router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {
        ga('set','page', event.urlAfterRedirects);
        ga('send', 'pageview');
    }
});