[英]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:关于如何:
gtag.js
be loaded in the proper window.document
and/or refer to the content.js
context of window
orgtag.js
加载到正确的window.document
和/或参考window
的content.js
上下文或window
object of the main page from the content.js
contextcontent.js
上下文访问主页的window
objectSince 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 消息传递协议的内容脚本。
message.type
) that identifies message as carrying analytics data (usually message.payload
).message.type
)的键(通常为message.payload
)。 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.