How to implement a facebook pixel in Angular?

故事扮演 提交于 2021-02-11 14:34:01

问题


I need to implement a facebook pixel in an angular proyect. I have the pixel in my index.html from src/index.html

<!doctype html>
<html lang="en">
  <head>
  .....
  </head>

<body>
  <app-root></app-root>
  <!-- Facebook Pixel Code -->
  <script>
    !function(f,b,e,v,n,t,s)
    {if(f.fbq)return;n=f.fbq=function(){n.callMethod?
    n.callMethod.apply(n,arguments):n.queue.push(arguments)};
    if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
    n.queue=[];t=b.createElement(e);t.async=!0;
    t.src=v;s=b.getElementsByTagName(e)[0];
    s.parentNode.insertBefore(t,s)}(window, document,'script',
    'https://connect.facebook.net/en_US/fbevents.js');
    fbq('init', 'XXXXXXXXXXXXX');
    fbq('track', 'PageView');
  </script>
  <noscript><img height="1" width="1" style="display:none"
  src="https://www.facebook.com/tr?id=XXXXXXXXXXXXX&ev=PageView&noscript=1"
  /></noscript>
  <!-- End Facebook Pixel Code -->
  <script>
  </script>
</body>
</html>

That's how it was "implemented" but it doesn't work, at least is what the facebook panel says.

What's is the right way to do this in a SPA made with Angular?


回答1:


I had the same problem and I come up with the following solution. It will work only for apps using Router. Hope it helps:

  1. In your app folder create a folder for the pixel service (e.g. facebook-pixel-service), then create the file for the service code (e.g. facebook-pixel.service.ts) and copy the code bellow that works like following:

    • The first time the app loads the root component of your app it will execute attaching the facebook script to the root component html. It will also call init and fire a PageView event for the current page (typically it will be path "/" on Router).
    • On all other executions that should correspond to the other paths/pages of your app, it will just fire the PageView event.

      import { Injectable } from '@angular/core';
      @Injectable({
        providedIn: 'root'
      })
      export class FacebookPixelService {
      
        private loadOk:boolean = false;
      
        constructor() { }
      
        load() {
          if (!this.loadOk) {
            (function (f: any, b, e, v, n, t, s) {
                if (f.fbq) return; n = f.fbq = function () {
                    n.callMethod ?
                        n.callMethod.apply(n, arguments) : n.queue.push(arguments)
                }; if (!f._fbq) f._fbq = n;
                n.push = n; n.loaded = !0; n.version = '2.0'; n.queue = []; t = b.createElement(e); t.async = !0;
                t.src = v; s = b.getElementsByTagName(e)[0]; s.parentNode.insertBefore(t, s)
            })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
            (window as any).fbq.disablePushState = true; //not recommended, but can be done
            (window as any).fbq('init', '381817369337156');
            (window as any).fbq('track', 'PageView');
            this.loadOk = true;
            console.log('Facebook pixel init run!')
          }
          else {
            (window as any).fbq('track', 'PageView');
            console.log('Facebook PageView event fired!')
          }
        }
      }
      
  2. On the same folder of the service create another file (e.g. facebook-pixel.provider.ts) for the provider that will inject the service on app.module. The code bellow will just create a provider that subscribe our pixel service to be called every time a Router event is fired and this event is a NavigationEnd which means it was a successful change on the path/page.

    import { Provider, APP_BOOTSTRAP_LISTENER, ComponentRef } from '@angular/core';
    import { Router, NavigationEnd } from '@angular/router';
    import { FacebookPixelService } from './facebook-pixel.service'
    
    export const FACEBOOK_PIXEL_PROVIDER: Provider = {
      provide: APP_BOOTSTRAP_LISTENER,
      multi: true,
      useFactory: FacebookPixelRouterInitializer,
      deps: [
        FacebookPixelService,
        Router
      ]
    };
    
    export function FacebookPixelRouterInitializer(
      $fpService: FacebookPixelService,
      $router: Router
    ) {
      return async (c: ComponentRef<any>) => {
        $router
          .events
          .subscribe(event => {
            if (event instanceof NavigationEnd) {
              console.log(`Navigated to URL: ${event.url}`);
              $fpService.load();
            }
          });
      };
    }
    
  3. Now, just inform the provider on the @NgModule directive on the app.moudle file. The framework will do the rest and make sure it will subscribe our provider to the Router and call it when appropriate. The snippet below shows how to inform the provider (search for FACEBOOK_PIXEL_PROVIDER):

    ...
    import { RouterModule, Routes } from '@angular/router';
    ...
    import { AppComponent } from './app.component';
    ...
    import { FACEBOOK_PIXEL_PROVIDER } from './facebook-pixel-service/facebook-pixel.provider'
    
    @NgModule({
      declarations: [
        AppComponent,
        ...
      ],
      imports: [
        ...
        RouterModule.forRoot([
          { path: '', Component: TheRootPath},
          { path: 'path1', Component: Path1},
          { path: 'path2', Component: Path2},
          { path: '**', component: PageNotFoundComponent },
        ]),
      ],
      providers: [
        FACEBOOK_PIXEL_PROVIDER
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    


来源:https://stackoverflow.com/questions/57318029/how-to-implement-a-facebook-pixel-in-angular

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!