Nuxt:在插件内部,如何将动态脚本标签添加到头部?
Nuxt: Inside a plugin, how to add dynamic script tag to head?
我正在尝试为 Nuxt 构建一个 Google 分析插件,它将从 CMS 获取跟踪 ID。我觉得我真的很接近。
我有一个仅在客户端加载的插件文件。该插件通过 plugins:[{ src: '~/plugins/google-gtag.js', mode: 'client' }]
数组从 nuxt.config.js
加载。
主要问题是 gtag 脚本需要 URL 中的 UA 代码,所以我不能直接将其添加到 nuxt.config.js
中的常规脚本对象中。我需要从商店获取那些 UA 代码(水合形式 nuxtServerInit
。
所以我在插件中使用 head.script.push
在 URL 中添加带有 UA 代码的 gtag 脚本。但这不会导致脚本在第一个页面加载时被添加,但它会影响所有后续页面转换。很明显我 运行 head.script.push
页面渲染太晚了。
但我不知道还有什么方法可以获取跟踪 ID,然后将脚本添加到头部。
// plugins/google.gtag.client.js with "mode": "client
export default ({ store, app: { head, router, context } }, inject) => {
// Remove any empty tracking codes
const codes = store.state.siteMeta.gaTrackingCodes.filter(Boolean)
// Add script tag to head
head.script.push({
src: `https://www.googletagmanager.com/gtag/js?id=${codes[0]}`,
async: true
})
console.log('added script')
// Include Google gtag code and inject it (so this.$gtag works in pages/components)
window.dataLayer = window.dataLayer || []
function gtag() {
dataLayer.push(arguments)
}
inject('gtag', gtag)
gtag('js', new Date())
// Add tracking codes from Vuex store
codes.forEach(code => {
gtag('config', code, {
send_page_view: false // necessary to avoid duplicated page track on first page load
})
console.log('installed code', code)
// After each router transition, log page event to Google for each code
router.afterEach(to => {
gtag('event', 'page_view', { page_path: to.fullPath })
console.log('afterEach', code)
})
})
}
我最终让它工作了,我们在 production here 中使用了它。
撰写本文时的代码如下所示:
export default ({ store, app: { router, context } }, inject) => {
// Remove any empty tracking codes
let codes = _get(store, "state.siteMeta.gaTrackingCodes", [])
codes = codes.filter(Boolean)
// Abort if no codes
if (!codes.length) {
if (context.isDev) console.log("No Google Anlaytics tracking codes set")
inject("gtag", () => {})
return
}
// Abort if in Dev mode, but inject dummy functions so $gtag events don't throw errors
if (context.isDev) {
console.log("No Google Anlaytics tracking becuase your are in Dev mode")
inject("gtag", () => {})
return
}
// Abort if we already added script to head
let gtagScript = document.getElementById("gtag")
if (gtagScript) {
return
}
// Add script tag to head
let script = document.createElement("script")
script.async = true
script.id = "gtag"
script.src = "//www.googletagmanager.com/gtag/js"
document.head.appendChild(script)
// Include Google gtag code and inject it (so this.$gtag works in pages/components)
window.dataLayer = window.dataLayer || []
function gtag() {
dataLayer.push(arguments)
}
inject("gtag", gtag)
gtag("js", new Date())
// Add tracking codes from Vuex store
codes.forEach(code => {
gtag("config", code, {
send_page_view: false // Necessary to avoid duplicated page track on first page load
})
// After each router transition, log page event to Google for each code
router.afterEach(to => {
gtag("config", code, { page_path: to.fullPath })
})
})
}
如果不在插件中,这是一本关于如何加载第 3 方脚本的好书:How to Load Third-Party Scripts in Nuxt.js
我正在尝试为 Nuxt 构建一个 Google 分析插件,它将从 CMS 获取跟踪 ID。我觉得我真的很接近。
我有一个仅在客户端加载的插件文件。该插件通过 plugins:[{ src: '~/plugins/google-gtag.js', mode: 'client' }]
数组从 nuxt.config.js
加载。
主要问题是 gtag 脚本需要 URL 中的 UA 代码,所以我不能直接将其添加到 nuxt.config.js
中的常规脚本对象中。我需要从商店获取那些 UA 代码(水合形式 nuxtServerInit
。
所以我在插件中使用 head.script.push
在 URL 中添加带有 UA 代码的 gtag 脚本。但这不会导致脚本在第一个页面加载时被添加,但它会影响所有后续页面转换。很明显我 运行 head.script.push
页面渲染太晚了。
但我不知道还有什么方法可以获取跟踪 ID,然后将脚本添加到头部。
// plugins/google.gtag.client.js with "mode": "client
export default ({ store, app: { head, router, context } }, inject) => {
// Remove any empty tracking codes
const codes = store.state.siteMeta.gaTrackingCodes.filter(Boolean)
// Add script tag to head
head.script.push({
src: `https://www.googletagmanager.com/gtag/js?id=${codes[0]}`,
async: true
})
console.log('added script')
// Include Google gtag code and inject it (so this.$gtag works in pages/components)
window.dataLayer = window.dataLayer || []
function gtag() {
dataLayer.push(arguments)
}
inject('gtag', gtag)
gtag('js', new Date())
// Add tracking codes from Vuex store
codes.forEach(code => {
gtag('config', code, {
send_page_view: false // necessary to avoid duplicated page track on first page load
})
console.log('installed code', code)
// After each router transition, log page event to Google for each code
router.afterEach(to => {
gtag('event', 'page_view', { page_path: to.fullPath })
console.log('afterEach', code)
})
})
}
我最终让它工作了,我们在 production here 中使用了它。
撰写本文时的代码如下所示:
export default ({ store, app: { router, context } }, inject) => {
// Remove any empty tracking codes
let codes = _get(store, "state.siteMeta.gaTrackingCodes", [])
codes = codes.filter(Boolean)
// Abort if no codes
if (!codes.length) {
if (context.isDev) console.log("No Google Anlaytics tracking codes set")
inject("gtag", () => {})
return
}
// Abort if in Dev mode, but inject dummy functions so $gtag events don't throw errors
if (context.isDev) {
console.log("No Google Anlaytics tracking becuase your are in Dev mode")
inject("gtag", () => {})
return
}
// Abort if we already added script to head
let gtagScript = document.getElementById("gtag")
if (gtagScript) {
return
}
// Add script tag to head
let script = document.createElement("script")
script.async = true
script.id = "gtag"
script.src = "//www.googletagmanager.com/gtag/js"
document.head.appendChild(script)
// Include Google gtag code and inject it (so this.$gtag works in pages/components)
window.dataLayer = window.dataLayer || []
function gtag() {
dataLayer.push(arguments)
}
inject("gtag", gtag)
gtag("js", new Date())
// Add tracking codes from Vuex store
codes.forEach(code => {
gtag("config", code, {
send_page_view: false // Necessary to avoid duplicated page track on first page load
})
// After each router transition, log page event to Google for each code
router.afterEach(to => {
gtag("config", code, { page_path: to.fullPath })
})
})
}
如果不在插件中,这是一本关于如何加载第 3 方脚本的好书:How to Load Third-Party Scripts in Nuxt.js