Sharing the same code between PWA and Native (iOS/Android) is a practice we have been using on our Ionic apps. An essencial service for many projects is Google Analytics (GA). We did a deep search to find the best option for our scenario. There was a main solution out there.
Ionic Native Google Analytics Plugin
It’s easy to add to your project, there are a lot of good tutorials like this. If you use just for native apps, it can be the best option. Otherwise for PWA the plugin just works when the app is compiled for browser platform and in this situation it produces a bigger webapp than necessary (6mb more for just one feature). Besides the size, browser platform will be depreceated according this comment of an Ionic Developer Team member.
UPDATED: July 25th, 2019
How we did using raw GA
I’ve used this project for tests :) feel free to clone/fork/contribute
index.html - added GA code snippet
...
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
</script>
...
src/app/analytics.service.ts
Install @types/google.analytics in order to allow works with js library in typescript.
$ npm install --save @types/google.analytics
Create a provider to work with GA.
$ ng g module shared --spec=false
$ ng g service analytics shared/services/analytics
import { Injectable } from '@angular/core';
declare var ga;
@Injectable({
providedIn: 'root'
})
export class AnalyticsService {
constructor() { }
setTracker(tracker) {
if ( !localStorage.getItem('ga:clientId') ) {
localStorage.setItem( 'ga:clientId', tracker.get('clientId') );
}
}
startTrackerWithId(id) {
ga('create', {
storage: 'none',
trackingId: id,
clientId: localStorage.getItem('ga:clientId')
});
ga('set', 'checkProtocolTask', null);
ga('set', 'transportUrl', 'https://www.google-analytics.com/collect');
ga(this.setTracker);
}
trackView(pageUrl: string, screenName: string) {
ga('set', {
page: pageUrl,
title: screenName
});
ga('send', 'pageview');
}
trackEvent(category, action, label?, value?) {
ga('send', 'event', {
eventCategory: category,
eventLabel: label,
eventAction: action,
eventValue: value
});
}
}
How to start tracking by id was inspired by this article who explains how solve some problems in native client.
src/app/app.module.ts
...
import { AnalyticsService } from './analytics.service';
...
@NgModule({
...
providers: [
...
AnalyticsService,
...
]
})
src/app/app.component.ts
...
import { AnalyticsService } from './analytics.service';
import { Router, NavigationStart } from '@angular/router';
import { Title } from '@angular/platform-browser';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
constructor(
...
private analyticsService: AnalyticsService,
public router: Router,
private title: Title,
) {
this.initializeApp();
}
initializeApp() {
//Start track passing Tracker Id
this.analyticsService.startTrackerWithId('XX-XXXXXXXX-X');
...
this.router.events
.subscribe(event => {
//observe router and when it start navigation it will track the view
if (event instanceof NavigationStart) {
let title = this.title.getTitle();
//get title if it was sent on state
if (this.router.getCurrentNavigation().extras.state) {
title = this.router.getCurrentNavigation().extras.state.title;
}
//pass url and page title
this.analyticsService.trackView(event.url, title);
}
});
}
}
Track Screen title
Sometimes besides the URL, you need to show more meaningful infos of your app on anlytics.
In our case it’s easier to understand Awesome new!
than /item/detail/123456
when you are reading analytics data.
So on items list, for each link we pass the title of item in state
attribute on template.
<a routerLink="/items/edit/123456" [state]="{ title: 'Awesome new!' }" routerDirection="root">
Awesome new!
</a>
example.ts - tracking some event
import { AnalyticsService } from './analytics.service';
export class ExamplePage {
constructor(
public analytics: AnalyticsService,
) {}
exampleEvent() {
this.analytics.trackEvent('User', 'Create User', 'Daniel');
}
}
Furthermore
- How to Implement Google Analytics in an Angular2 App?;
- Using Google Analytics in an Ionic app without a plugin;
- Ionic Native Google Analytics Plugin;
- Ionic - Global navigation change event;
- IONIC2 App Metrics using Google Analytics;
- Angular 4+ using Google Analytics;
- Integrating Google Analytics With Angular 2+