1
1
import { PixelEventName , PixelConfiguration , PixelEventProperties } from './pixel.models' ;
2
- import { Inject , Injectable , Optional } from '@angular/core' ;
2
+ import { Inject , Injectable , Optional , PLATFORM_ID , Renderer2 , RendererFactory2 } from '@angular/core' ;
3
3
import { NavigationEnd , Router } from '@angular/router' ;
4
+ import { DOCUMENT , isPlatformBrowser } from '@angular/common' ;
4
5
import { filter } from 'rxjs/operators' ;
5
6
6
- declare var fbq : any ;
7
+ declare const fbq : any ;
7
8
8
9
@Injectable ( {
9
10
providedIn : 'root'
10
11
} )
11
12
export class PixelService {
12
13
14
+ private doc : Document ;
15
+ private renderer : Renderer2
16
+
13
17
constructor (
14
18
@Inject ( 'config' ) private config : PixelConfiguration ,
15
- @Optional ( ) private router : Router
19
+ @Inject ( DOCUMENT ) private injectedDocument : any ,
20
+ @Inject ( PLATFORM_ID ) private platformId : Object ,
21
+ @Optional ( ) private router : Router ,
22
+ private rendererFactory : RendererFactory2
16
23
) {
17
24
25
+ // DOCUMENT cannot be injected directly as Document type, see https://github.com/angular/angular/issues/20351
26
+ // It is therefore injected as any and then cast to Document
27
+ this . doc = injectedDocument as Document ;
28
+ this . renderer = rendererFactory . createRenderer ( null , null ) ;
29
+
18
30
if ( router ) {
19
31
// Log page views after router navigation ends
20
32
router . events . pipe ( filter ( event => event instanceof NavigationEnd ) ) . subscribe ( event => {
@@ -33,7 +45,7 @@ export class PixelService {
33
45
* - Adds the script to page's head
34
46
* - Tracks first page view
35
47
*/
36
- initialize ( pixelId = this . config . pixelId ) : void {
48
+ initialize ( pixelId ?: string ) : void {
37
49
if ( this . isLoaded ( ) ) {
38
50
console . warn ( 'Tried to initialize a Pixel instance while another is already active. Please call `remove()` before initializing a new instance.' ) ;
39
51
return ;
@@ -58,8 +70,12 @@ export class PixelService {
58
70
track (
59
71
eventName : PixelEventName ,
60
72
properties ?: PixelEventProperties
61
- ) : void {
62
- if ( ! this . isLoaded ( ) ) {
73
+ ) : void {
74
+ if ( ! isPlatformBrowser ( this . platformId ) ) {
75
+ return ;
76
+ }
77
+
78
+ if ( ! this . isLoaded ( ) ) {
63
79
console . warn ( 'Tried to track an event without initializing a Pixel instance. Call `initialize()` first.' ) ;
64
80
return ;
65
81
}
@@ -80,7 +96,11 @@ export class PixelService {
80
96
* @param properties Optional properties of the event
81
97
*/
82
98
trackCustom ( eventName : string , properties ?: object ) : void {
83
- if ( ! this . isLoaded ( ) ) {
99
+ if ( ! isPlatformBrowser ( this . platformId ) ) {
100
+ return ;
101
+ }
102
+
103
+ if ( ! this . isLoaded ( ) ) {
84
104
console . warn ( 'Tried to track an event without initializing a Pixel instance. Call `initialize()` first.' ) ;
85
105
return ;
86
106
}
@@ -97,6 +117,9 @@ export class PixelService {
97
117
* @param pixelId The Facebook Pixel ID to use
98
118
*/
99
119
private addPixelScript ( pixelId : string ) : void {
120
+ if ( ! isPlatformBrowser ( this . platformId ) ) {
121
+ return ;
122
+ }
100
123
101
124
const pixelCode = `
102
125
var pixelCode = function(f,b,e,v,n,t,s)
@@ -110,25 +133,32 @@ export class PixelService {
110
133
fbq('init', '${ pixelId } ');
111
134
fbq('track', 'PageView');` ;
112
135
113
- const scriptElement = document . createElement ( 'script' ) ;
114
- scriptElement . setAttribute ( 'id' , 'pixel-script' ) ;
115
- scriptElement . type = 'text/javascript' ;
116
- scriptElement . innerHTML = pixelCode ;
117
- document . getElementsByTagName ( 'head' ) [ 0 ] . appendChild ( scriptElement ) ;
136
+
137
+ const scriptElement = this . renderer . createElement ( 'script' ) ;
138
+ this . renderer . setAttribute ( scriptElement , 'id' , 'pixel-script' ) ;
139
+ this . renderer . setAttribute ( scriptElement , 'type' , 'text/javascript' ) ;
140
+ this . renderer . setProperty ( scriptElement , 'innerHTML' , pixelCode ) ;
141
+ this . renderer . appendChild ( this . doc . head , scriptElement ) ;
118
142
}
119
143
120
144
/** Remove Facebook Pixel tracking script from the application */
121
145
private removePixelScript ( ) : void {
122
- const pixelElement = document . getElementById ( 'pixel-script' ) ;
146
+ if ( ! isPlatformBrowser ( this . platformId ) ) {
147
+ return ;
148
+ }
149
+ const pixelElement = this . doc . getElementById ( 'pixel-script' ) ;
123
150
if ( pixelElement ) {
124
151
pixelElement . remove ( ) ;
125
152
}
126
153
}
127
154
128
155
/** Checks if the script element is present */
129
156
private isLoaded ( ) : boolean {
130
- const pixelElement = document . getElementById ( 'pixel-script' ) ;
131
- return ! ! pixelElement ;
157
+ if ( isPlatformBrowser ( this . platformId ) ) {
158
+ const pixelElement = this . doc . getElementById ( 'pixel-script' ) ;
159
+ return ! ! pixelElement ;
160
+ }
161
+ return false ;
132
162
}
133
163
134
164
}
0 commit comments