vue.js - Facebook Pixel 与 Conversion API - 帮助跟踪相同的事件 ID

标签 vue.js nuxt.js facebook-pixel

我在使用 Facebook Conversion API 复制 Nuxt.js (Vue) 项目中像素的“PageView”事件时遇到了一些令人沮丧的问题。

我最初删除了这个包代码,以便我可以修改以包含每个“PageView”事件的 eventID:https://github.com/WilliamDASILVA/nuxt-facebook-pixel-module#readme

我的“PageView”事件工作流程是这样的:

  1. 在 Vue 路由器“afterEach”钩子(Hook)上,调用跟踪函数。
  2. 当我调用跟踪函数时,对 API 进行异步调用,这将通过“PageView”事件触发服务器转化 API。 API 调用返回完全相同的 eventID,因此我们可以在 FE 上进行复制。
  3. 使用给定的 eventID 调用 Facebook 的 Pixel 跟踪方法。

初始加载工作正常:

Duplicated PageView Event

但是,路线更改后的后续调用不起作用。服务器级别事件和浏览器级别事件都会被跟踪,但不会重复。

Not Duplicated after vue router change

我注意到的第一件事是没有为浏览器调用设置 eventID。我花了几个小时确保使用 eventID 对浏览器中的 facebook 像素调用了正确的函数,确实如此。

我找到了https://gist.github.com/sunderls/dfd5293a8b8f24a4ef37189a1d8c1b46上网,并开始尝试弄清楚发生了什么。当调用浏览器历史记录的replacestate/pushstate时,事件处理程序似乎会自动添加到像素中。这可以解释为什么没有 eventID 被传递,它会自动触发。

查看 Facebook 文档,我发现我可以设置:

fbq.disablePushState = true

这将阻止像素添加这些事件监听器。但是,当我在上面添加这行代码时,在初始页面加载后我没有收到任何后续的“PageView”事件,只有服务器事件通过。

这是我的插件源代码:

import { Minimatch } from "minimatch"
import axios from "axios"
import cookie from "js-cookie"

/**
 * @class Fb
 */
class Fb {
  constructor (fbq, options, eventUrl) {
    this.options = options
    this.fbq = fbq
    this.eventUrl = eventUrl

    this.isEnabled = !options.disabled
  }

  setPixelId (pixelId) {
    this.options.pixelId = pixelId
    this.init()
  }

  /**
   * @method enable
   */
  enable () {
    this.isEnabled = true
    this.init()
    this.track()
  }

  /**
   * @method disable
   */
  disable () {
    this.isEnabled = false
  }

  /**
   * @method init
   */
  init () {
    this.query('init', this.options.pixelId)
  }

  /**
   * @method track
   */
  async track (event = null, parameters = null, eventId = null) {
    if (!event) {
      event = this.options.track
    }

    if (this.eventUrl && !eventId) {
      if (cookie.get("auth._token.cookie")) {
        axios.defaults.headers.common["Authorization"] = cookie.get("auth._token.cookie");
      }
      try {
        let url = this.eventUrl
        const queryString = []
        if (event === "PageView") {
          queryString.push("url=" + window.location.href.split('?')[0])
          queryString.push("view=true")
        }
        if (cookie.get("_fbp")) {
          queryString.push(`_fbp=${cookie.get("_fbp")}`)
        }
        if (cookie.get("_fbc")) {
          queryString.push(`_fbc=${cookie.get("_fbc")}`)
        }
        if (queryString.length !== 0) {
          url += "?" + queryString.join("&")
        }
        const {data: {data}} = await axios.get(url)
        eventId = data.event_id
      } catch (err) {
        console.error(err)
      }
    }

    this.query('track', event, parameters, eventId)
  }

  /**
   * @method query
   * @param {string} cmd
   * @param {object} option
   * @param {object} parameters
   */
  query (cmd, option, parameters = null, eventId = null) {
    if (this.options.debug) log('Command:', cmd, 'Option:', option, 'Additional parameters:', parameters, 'Event Id:', eventId)
    if (!this.isEnabled) return

    if (!parameters && !eventId) {
      this.fbq(cmd, option)
    } else if (parameters && !eventId) {
      this.fbq(cmd, option, parameters)
    } else {
      this.fbq(cmd, option, {}, {eventID: eventId})
    }
  }
}

function getMatchingPixel (options, path) {
  return options.pixels.find(pixel => {
    const routeIndex = pixel.routes.findIndex(route => {
      const minimatch = new Minimatch(route)
      return minimatch.match(path)
    })

    return routeIndex !== -1
  })
}

function log (...messages) {
  console.info.apply(this, ['[nuxt-facebook-pixel-module]', ...messages])
}

export default (ctx, inject) => {
  let _fbq
  const parsedOptions = <%= JSON.stringify(options) %>
  const isDev = parsedOptions.dev && !parsedOptions.debug

  if (isDev) log('You are running in development mode. Set "debug: true" in your nuxt.config.js if you would like to trigger tracking events in local.')

  const { path } = ctx.route
  const matchingPixel = getMatchingPixel(parsedOptions, path)

  const pixelOptions = Object.assign({}, matchingPixel || parsedOptions)

  /* eslint-disable */
  if (typeof window !== 'undefined') {
    ((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 = pixelOptions.version;
      n.queue = [];
      t = b.createElement(e);
      t.async = true;
      t.defer = true;
      t.src = v;
      s = b.getElementsByTagName('body')[0];
      s.parentNode.appendChild(t, s);

      _fbq = fbq;

      if (!isDev && !pixelOptions.disabled) {
        if (pixelOptions.manualMode) {
          fbq('set', 'autoConfig', false, pixelOptions.pixelId)
        }
        // fbq.disablePushState = true
        fbq('init', pixelOptions.pixelId)
        // fbq('track', pixelOptions.track)
      }
    })(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
  }
  /* eslint-enable */

  const instance = new Fb(_fbq, pixelOptions, parsedOptions.eventUrl)

  if (ctx.app && ctx.app.router) {
    const router = ctx.app.router
    router.afterEach(({ path }) => {
      /**
       * Change the current pixelId according to the route.
       */
      const matchingPixel = getMatchingPixel(parsedOptions, path)

      const pixelOptions = Object.assign({}, matchingPixel || parsedOptions)
      if (pixelOptions.pixelId !== instance.options.pixelId) {
        instance.setPixelId(pixelOptions.pixelId)
      }

      /**
       * Automatically track PageView
       */
      if (parsedOptions.autoPageView) {
        instance.track('PageView')
      }
    })
  }

  /* eslint-enable */
  ctx.$fb = instance
  inject('fb', instance)
}

所有设置均已正确设置,插件才能正常工作。我没有使用多个 Facebook Pixel。

非常感谢您帮助解决这个问题。

最佳答案

我通过设置使其工作:

fbq.disablePushState = true
fbq.allowDuplicatePageViews = true

查看美化后的像素代码:https://gist.github.com/sunderls/dfd5293a8b8f24a4ef37189a1d8c1b46

我发现在track函数中有这样的内容:

if (isPageview && wa.allowDuplicatePageViews === false && ca[methodCall.id] === true) continue;

因此,出于某种原因,允许重复的页面 View 是有效的。

关于vue.js - Facebook Pixel 与 Conversion API - 帮助跟踪相同的事件 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68475242/

相关文章:

javascript - vue @click 函数 on::after css element - close btn

ios - Facebook 像素事件购买未注册 iOS 销售

javascript - javascript 中的 !function 是什么?

javascript - [Vue 警告] : Cannot find element

javascript - 无法将项目添加到数组

javascript - 如何只触发一次 vue 方法,而不是每次

vue.js - Nuxt.js中如何根据窗口的存在动态切换组件?

vue.js - Nuxt.js npm run generate 后找不到文件

laravel - 在javascript代码中重定向惯性js和jetstream

javascript - 如何在 Google 跟踪代码管理器中的不同 HTML 位置添加标签?