我在使用 Facebook Conversion API 复制 Nuxt.js (Vue) 项目中像素的“PageView”事件时遇到了一些令人沮丧的问题。
我最初删除了这个包代码,以便我可以修改以包含每个“PageView”事件的 eventID:https://github.com/WilliamDASILVA/nuxt-facebook-pixel-module#readme
我的“PageView”事件工作流程是这样的:
- 在 Vue 路由器“afterEach”钩子(Hook)上,调用跟踪函数。
- 当我调用跟踪函数时,对 API 进行异步调用,这将通过“PageView”事件触发服务器转化 API。 API 调用返回完全相同的 eventID,因此我们可以在 FE 上进行复制。
- 使用给定的 eventID 调用 Facebook 的 Pixel 跟踪方法。
初始加载工作正常:
但是,路线更改后的后续调用不起作用。服务器级别事件和浏览器级别事件都会被跟踪,但不会重复。
我注意到的第一件事是没有为浏览器调用设置 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/