简体   繁体   English

在基于 React 的 Chrome 扩展中实现 Google Analytics gtag.js 时遇到问题

[英]Trouble implementing Google Analytics gtag.js in React-based Chrome Extension

My problem in a nutshell: The window object that gtag.js operates on and the window object available in my react context (a content.js context) are different objects, and so I can't write events from my react code -- meaning I can't use analytics in my extension. My problem in a nutshell: The window object that gtag.js operates on and the window object available in my react context (a content.js context) are different objects, and so I can't write events from my react code -- meaning我无法在我的扩展程序中使用分析。

More deets:更多细节:

In react <script> tags can't be loaded directly for various reasons .在 react <script>标签由于各种原因无法直接加载。 So I've change the documentation implementation:所以我改变了文档实现:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'GA_MEASUREMENT_ID');
</script>

To

export const gtag = (...args) => {
  window.dataLayer.push(args)
}

export const loadAnalytics = (ga_property) => {
  const script      = windowdocument.createElement("script")
  script.src        = `https://www.googletagmanager.com/gtag/js?id=${ga_property}`
  script.async      = true
  window.document.body.appendChild(script)
  window.dataLayer = window.dataLayer || []
  gtag('js', new Date())
  gtag('config', ga_property, { 'transport_type': 'beacon'})
  gtag('event', 
      'test', {
      event_category: 'lookup',
      event_label: 'test'
    }
  )
}

... ...

  componentDidMount() {
    loadAnalytics("UA-175XXXXXX-1")
  }

I've come to understand through much research and gnashing of teeth that the window object in my content.js and the window object that is acted on in gtag.js once it is loaded are not the same object, and are intentionally "shadows" of each other, but still separate objects. I've come to understand through much research and gnashing of teeth that the window object in my content.js and the window object that is acted on in gtag.js once it is loaded are not the same object, and are intentionally "shadows"彼此,但仍然是独立的对象。 From the documentation:从文档中:

"Content scripts live in an isolated world, allowing a content script to makes changes to its JavaScript environment without conflicting with the page or additional content scripts. “内容脚本存在于一个孤立的世界中,允许内容脚本对其 JavaScript 环境进行更改,而不会与页面或其他内容脚本发生冲突。

Isolated worlds do not allow for content scripts, the extension, and the web page to access any variables or functions created by the others."孤立的世界不允许内容脚本、扩展和 web 页面访问其他人创建的任何变量或函数。”

From what I can tell this seems to be irreconcilable without a re-write of the gtag.js source.据我所知,如果不重新编写gtag.js源代码,这似乎是不可调和的。

For reasons I still don't understand this code which references window.document由于某些原因,我仍然不明白引用window.document代码

  const script      = window.document.createElement("script")
  script.src        = `https://www.googletagmanager.com/gtag/js?id=${ga_property}`
  script.async      = true
  window.document.body.appendChild(script)

And this code in the same file which references window.document并且此代码在引用window.document的同一文件中

export const gtag = (...args) => {
  window.dataLayer.push(args)
}

End up pointing to two different window objects.最终指向两个不同的 window 对象。

This post seems to reinforce that these two contexts can't communicated directly in terms of objects and functions (only messages). 这篇文章似乎强化了这两个上下文不能直接根据对象和功能(仅消息)进行通信。

For gtag.js to work in an extension, I'd need to be able to call window.dataLayer.push(...) on the window of the main web page from inside my chrome extension.为了gtag.js在扩展程序中工作,我需要能够从 mychrome 扩展程序内部的主 web 页面的window上调用window.dataLayer.push(...) And that doesn't seem possible.这似乎是不可能的。

Any bright ideas out there as to how to either:关于如何:

  1. Make gtag.js be loaded in the proper window.document and/or refer to the content.js context of window or使gtag.js加载到正确的window.document和/或参考windowcontent.js上下文或
  2. be able to access the window object of the main page from the content.js context能够从content.js上下文访问主页的window object

Since extension code can have multiple contexts, it would be wise use the principle of separation of concerns to avoid multiple document issue altogether.由于扩展代码可以有多个上下文,明智的做法是使用关注点分离的原则来完全避免多个document问题。

When developing extensions it is advised to run majority of your code in the background, to make use of the separate JavaScript runtime allocated for your code by the browser (and avoid slowing down the pages user is visiting or the code which appears as your extension UI).在开发扩展时,建议在后台运行大部分代码,以利用浏览器为您的代码分配的单独 JavaScript 运行时(并避免减慢用户正在访问的页面或显示为您的扩展 UI 的代码)。 Additionally, in most cases, it is a good idea to ship the code you want to run packaged within the extension bundle.此外,在大多数情况下,最好将要运行的代码打包在扩展包中。 If you want to load an external resource, to your background script "document", you can use XHR and eval to execute code.如果你想加载一个外部资源,到你的后台脚本“文档”,你可以使用XHR 和 eval来执行代码。

When code is executed in the background, it is available to your extension UI and content scripts using the extension and DOM messaging protocols.当代码在后台执行时,它可用于您的扩展 UI 和使用扩展和 DOM 消息传递协议的内容脚本。

  1. First, initialize your extension in the context of your background script(s).首先,在后台脚本的上下文中初始化您的扩展。
  2. Then, register a message handler which will evaluate messages sent by other extension code and look for a key (usually message.type ) that identifies message as carrying analytics data (usually message.payload ).然后,注册一个消息处理程序,该处理程序将评估其他扩展代码发送的消息并查找将消息标识为携带分析数据(通常为message.type )的键(通常为message.payload )。
  3. Read the content of the messages that match the criteria in the handler, and use the supplied information to invoke analytics APIs.读取与处理程序中的条件匹配的消息内容,并使用提供的信息调用分析 API。
  4. Finally, send analytics events occurring in your UI or content scripts as messages to the background script.最后,将您的 UI 或内容脚本中发生的分析事件作为消息发送到后台脚本。

This way your background script is the only place where analytics is set up, clearing up document ambiguity, your code is cleaner, because there is only one place where analytics code is accessed and the extension runs smoother because it's UI and content scripts don't need to load or know about analytics code.这样,您的后台脚本是唯一设置分析的地方,清除document歧义,您的代码更干净,因为只有一个地方可以访问分析代码并且扩展运行更流畅,因为它的 UI 和内容脚本没有需要加载或了解分析代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 GA4 谷歌分析。 gtag.js 发送请求有几秒钟的延迟,而不是立即 - GA4 Google Analytics. gtag.js sends a request with a delay of a few seconds, not instantly 无法在React SPA中实现gtag - Trouble implementing gtag in React SPA 在 React 中添加谷歌分析 gtag 代码片段 - Add google analytics gtag code snippet in React 其他加载完成后,使用Webpack加载Google Analytic的gtag.js - Loading Google Analytic's gtag.js using Webpack after everything else loads 在基于反应的数据表中封装逻辑方面需要指导 - Need guidance on encapsulating logic in a react-based data table 赛普拉斯 - 拖放在基于反应的网站上不起作用 - Cypress - Drag and drop not working on a react-based website Gtag 和 Google Analytics 事件和网页浏览量衡量 - Gtag and Google Analytics events and page view measurement 在 Gatsby 应用程序中检测到多个全局站点标记 (gtag.js) 安装 - Multiple installations of Global site tag (gtag.js) detected in Gatsby application 在 Chrome 扩展中使用 react js - using react js in Chrome extension 在 React.js 中跟踪 Google AdWords 中的转化时,如何使用“gtag_report_conversion”? - How do I use 'gtag_report_conversion' when tracking conversions in Google AdWords in React.js?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM