Nuxt:如何在服务器端动态地将内容/脚本添加到头部 [英] Nuxt: How to add content/scripts to the head dynamically on server side

查看:203
本文介绍了Nuxt:如何在服务器端动态地将内容/脚本添加到头部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在服务器端 Nuxt 的头部动态添加内容?

How can I add dynamically content to the head in Nuxt on server side?

我试图在这里重写这个仅支持静态 ID 的模块:https://github.com/nuxt-community/modules/blob/master/packages/google-tag-manager/index.js

I was trying to rewrite this module here which supports only static id's: https://github.com/nuxt-community/modules/blob/master/packages/google-tag-manager/index.js

(我的 id 来自商店(商店正在从休息调用中获取 id))

(My id is coming from the store (The store is fetching the id from a rest call))

这是将内容添加到头部的函数:

This is the function which is adding the content to the head:

export default function addheadcode(head, id) {
  const options = {
    id: id,
    layer: 'dataLayer',
    pageTracking: true,
    pageViewEventName: 'nuxtRoute',
    respectDoNotTrack: false,
    query: {},
    scriptURL: '//www.googletagmanager.com/gtm.js',
    noscriptURL: '//www.googletagmanager.com/ns.html',
    env: {} // env is supported for backward compability and is alias of query
  }

  const queryParams = Object.assign({}, options.env, options.query)

  queryParams.id = options.id

  if (options.layer) {
    queryParams.l = options.layer
  }

  const queryString = Object.keys(queryParams)
    .filter(key => queryParams[key] !== null && queryParams[key] !== undefined)
    .map(
      key =>
        `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`
    )
    .join('&')

  head = head || {}
  head.noscript = head.noscript || []
  head.script = head.script || []

  head.script.push({
    hid: 'gtm',
    src:
      (options.scriptURL || '//www.googletagmanager.com/gtm.js') +
      '?' +
      queryString,
    async: true
  })

  head.noscript.push({
    hid: 'gtm-noscript',
    innerHTML: `<iframe src="${options.noscriptURL}?${queryString}" height="0" width="0" style="display:none;visibility:hidden"></iframe>`,
    pbody: true
  })

  head.__dangerouslyDisableSanitizersByTagID =
    head.__dangerouslyDisableSanitizersByTagID || {}
  head.__dangerouslyDisableSanitizersByTagID['gtm-noscript'] = ['innerHTML']
}

这是我只在服务器端执行的中间件/middleware/gtm.js

And this is my middleware which I am executing only on server side /middleware/gtm.js

import gtmAddheadcode from '~/src/googletagmanager.js'

export default function({ store, app }) {
  if (process.server) {
    const gtmID = store.getters['websiteskeleton/googelTagManagerId']
    gtmAddheadcode(app.head, gtmID)
  }
}

问题:在第一次通话时,它似乎工作正常.这是我可以在客户端看到的输出:

Problem: On the first call it seems to work fine. Here is the output which I can see on client side:

<script data-n-head="true" src="//www.googletagmanager.com/gtm.js?id=GTM-P4FZ3XX&amp;l=dataLayer" async="true"></script><noscript data-n-head="true" data-hid="gtm-noscript" pbody="true"><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXX&l=dataLayer" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

如果我刷新该页面.我看到相同的内容加倍.如果我再次刷新它,我会看到它三倍.

If I refresh that page. I see the same content double. If i refresh it again I see it threefold.

1) 为什么 Nuxt 会保存应用程序的这个状态?

1) Why is Nuxt saving this state of the application?

2) 我该怎么做才能解决这个问题?

2) What can I do to fix this problem?

我用代码创建了一个 git 存储库.问题只发生在生产模式!运行 dev 时你看不到它.示例存储库

I created a git repository with the code. The problem occurs only in production mode! You can't see it while running dev. Example repository

编辑 2:这是一个将被修复的错误:https://github.com/nuxt/nuxt.js/issues/6786#event-2893743506

EDIT 2: It is a bug an will be fixed: https://github.com/nuxt/nuxt.js/issues/6786#event-2893743506

推荐答案

回答您的问题:

1.

这确实听起来像是某个地方的错误.Nuxt 不应该像这样跨请求保存状态.这对我来说似乎是一个大问题,只需省略 hid 就很容易在您的应用中导致内存泄漏.我建议在 Nuxt github 页面上打开一个问题来解决这个问题.

This does indeed sound like a bug somewhere. Nuxt should not be saving state like this across requests. This seems like a huge issue to me, making it incredibly easy to cause memory leaks in your app by just omitting the hid. I would suggest opening an issue on the Nuxt github page addressing this.

我有根据的猜测是 Nuxt 可能会保留 vue-meta 的状态,该库用于处理 head 标签,并假设用户将使用hid 在它们的元素上以在需要时替换它们.

My educated guess is that Nuxt might persist the state of vue-meta, the library that's used to work with the head tag, and assumes that users will be using hid on their elements to replace them when needed.

2.

我唯一的建议是将 hid 添加到您的脚本对象中,将其命名为诸如gtag"之类的常见名称.

The only suggestion I have is to add hid to your script object, naming it something common like 'gtag'.

  head.script.push({
    hid: 'gtag',
    src:
      (options.scriptURL || '//www.googletagmanager.com/gtm.js') +
      '?' +
      queryString,
    async: true
  })

这篇关于Nuxt:如何在服务器端动态地将内容/脚本添加到头部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆