angulartics / angulartics-google-analytics

Google Analytics plugin for Angulartics
MIT License
133 stars 86 forks source link

Allow to specify a title #30

Closed danielsmink closed 7 years ago

danielsmink commented 8 years ago

When sending a pageview it would be nice if we could send a custom title along with it. In our application detail pages of objects each have their own title. Right now the plugin just sends the route.

maliknur commented 8 years ago

'+' for such feature

timelf123 commented 8 years ago

This should be added in the core readme/docs as an exmaple imo, as there are so many ways to do page titles in a SPA..

DanWilkerson commented 8 years ago

Seems to me like this should be handled by using the API directly (won't that be necessary anyhow? Since each route would have to be configured?) and turning off auto pageviews.

m-spyratos commented 8 years ago

Per Google's docs, I would expect something like this:

$analytics.pageTrack([page], [fieldsObject]);

That way we could optionally specify title, location and page. Shouldn't Angulartics at least support the API standards?

timelf123 commented 8 years ago

@DanWilkerson exactly right this should be handled via the api - @m-spyratos currently the core pageTrack method if using route based auto tracking is $analytics.pageTrack(url, $location); but if you turn it off and use the API directly you could do something like this:

Dynamic title resolution

There are many like it but this one is mine ;) Not a huge fan of using rootScope, so any alternative methods are appreciated. Includes a directive for the <title> element that also fires an event when the title changes, and stores page titles on route prop

Routes file with resolve

(data.pageTitle can be vanilla string too, no need for resolves)

.state('dynamicTitle', {
      url: '/title/:id',
      templateUrl: 'title.html',
      resolve: {
        titleResolve: loadTitle
      },
      data: {
        pageTitle: 'This title is {{titleResolve.title || "dynamic"}}'
      }
    })
....
    loadTitle.$inject = ['$stateParams', 'Service'];

    function loadTitle($stateParams, Service) {
      return Service.get({
        id: $stateParams.id
      }).$promise;
    }

Directive

Use in html like: <title page-title>{{appName}} - {{title}}</title> (in my example the curly braces are NOT ANGULAR. they are for my server side templating to assign a default title to the index.html)

(function () {
  'use strict';

  angular.module('myUtils')
    .directive('pageTitle', pageTitle);

  pageTitle.$inject = ['$rootScope', '$interpolate', '$state'];

  function pageTitle($rootScope, $interpolate, $state) {
    var directive = {
      restrict: 'A',
      link: link
    };

    return directive;

    function link(scope, element) {
      $rootScope.$on('$stateChangeSuccess', listener);

      function listener(event, toState) {
        var applicationCoreTitle = 'Ideawake',
          separateBy = ' - ';
        if (toState.data && toState.data.pageTitle) {
          var stateTitle = $interpolate(toState.data.pageTitle)($state.$current.locals.globals);
          element.html(stateTitle + separateBy + applicationCoreTitle);
          $rootScope.$emit('$titleChangeSuccess', stateTitle + separateBy + applicationCoreTitle);
        } else {
          element.html(applicationCoreTitle);
          $rootScope.$emit('$titleChangeSuccess', applicationCoreTitle);
        }
      }
    }
  }
}());

Finally, make the page track call!

    $rootScope.$on('$titleChangeSuccess', function(event, title) {
      // call analytics.pageTrack
      // console.log('title changed to ', title)
    })

I need to do some more testing on the last piece to make sure there is not a race condition where $titleChangeSuccess happens before $stateChangeSuccess and how it plays with ui-router 1.0.X transitions

DanWilkerson commented 8 years ago

@m-spyratos I see what you mean. I'll see if we can make this work, but Angulartics isn't designed specifically for Google Analytics - it's meant to be a plugin supporting a broad range of analytics providers with a standard syntax. There are tradeoffs, of course.

m-spyratos commented 8 years ago

@DanWilkerson I totally understand that Angulartics is meant to be generic. To be honest though, I am not so sure that this is a good thing if it poses such limitations. Of course it's not a deal breaker as you can create you own methods to handle specific scenarios, but I think this defeats its purpose.

Nonetheless, this is a great product to setup analytics to your project fast and easy, so it would be great to overcome these issues.

DanWilkerson commented 8 years ago

@m-spyratos I hear you. It would be nice to support the basic fields object. I'll be able to take a look at this probably this weekend, but don't hold me to it 😄

m-spyratos commented 8 years ago

@DanWilkerson Thanks! No worries about time. If I can be of any help let me know.

DanWilkerson commented 8 years ago

@timelf123 Looks like we could switch from whitelisting properties passed to angulartics.pageTrack() et al. I've been following that convention because it was in place before, but I don't see any reason not to just pass a clone of properties to GA, e.g.

    if ($analyticsProvider.settings.ga.disablePageTracking) return;

    dispatchToGa('pageview', 'send', angular.extend(dimensionsAndMetrics(properties), {
      hitType: 'pageview',
      page: path
    }));

becomes

    if ($analyticsProvider.settings.ga.disablePageTracking) return;

    dispatchToGa('pageview', 'send', angular.extend({}, properties, {
      hitType: 'pageview',
      page: path
    }));

Any reason not to do this? This would let users take full advantage of any GA config they'd like without us having to add the property to the whitelist.

DanWilkerson commented 7 years ago

@timelf123 just wanted to ping you on this again. I've got a PR in the oven to fix this, but before I submitted I wanted to see what you thought.

timelf123 commented 7 years ago

I'm good with a PR at the minimum ;) The idea looks sound though - no reason we shouldn't conform to the GA API

DanWilkerson commented 7 years ago

@timelf123 see #88

DanWilkerson commented 7 years ago

@danielsmink @m-spyratos this is merged in - you can specify a title by passing it with your properties object. Docs update is overdue, apologies.

$analytics.pageTrack({
  title: 'This is the title'  // Is set to the 'Page Title' Dimension in Google Analytics
});
danielsmink commented 7 years ago

Great thanks!

hamxiaoz commented 7 years ago

@danielsmink I created a PR updating the main site:

https://github.com/angulartics/angulartics.github.io/pull/9

I know this is for GA only but there is no GA doc available so I updated the main site. The alternative is that we add GA examples to the GA readme

Let me know what works best.