老胡茶室
老胡茶室

排错:Google Analytics 嵌入 Astro 工程中无法正常工作

冯宇

症状

在将 Google Analytics 嵌入 Astro 工程后,发现 dev 模式运行是正常的,但是 build 之后在产品环境运行的时候,Google Analytics 无法正常工作。

具体表现是可以正常加载 Google Analytics 的脚本,但是在控制台中查看网络请求时,发现没有发送任何数据到 Google Analytics。

分析

起初以为很简单,直接复制 Google Analytics 的代码到 Astro 工程中就可以了。当时代码类似于这样:

// src/components/BaseHead.astro
---
// ...
---

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

  gtag("config", "G-********");
</script>

结果部署之后过了几天,发现 Google Analytics 的数据一直没有更新。于是开始排查问题。

检查了 Google Analytics 的设置,确认跟踪 ID 是正确的。然后检查了 Astro 的配置,发现没有任何问题。

然后检查产品环境的网页代码,发现这里的 script 被优化编译了,这部分代码最终编译后的结果类似于这样 (格式化后,实际是压缩为一行的):

<!-- Google tag (gtag.js) -->
<script
  async
  src="https://www.googletagmanager.com/gtag/js?id=G-********"
></script>
<script type="module">
  window.dataLayer = window.dataLayer || [];
  function a() {
    dataLayer.push(arguments);
  }
  a("js", new Date());
  a("config", "G-********");
</script>
<link rel="stylesheet" href="/_astro/_slug_.D9Xwuj1P.css" />

代码明显被混淆了,也就是经过了编译和优化。于是开始怀疑是不是因为这个原因导致 Google Analytics 无法正常工作。

解决方案

翻阅官方文档,发现官方文档对于引用第三方 js 的时候,专门有说明,详见官方文档 client-side-scripts/#load-external-scripts

原来,在 .astro 文件中直接使用 <script> 标签加载脚本的时候,Astro 会对其进行编译和优化,但是对于第三方脚本,很显然不能这么做。于是需要使用 is:inline 属性来告诉 Astro 不要对这个脚本进行编译和优化。

简而言之,如果你的 js 是第三方脚本,或者存储在 public/js/ 目录下,就需要使用 is:inline 属性跳过 Astro 的编译优化。于是修改代码如下:

// src/components/BaseHead.astro
---
// ...
---
<!-- Google tag (gtag.js) -->
<script is:inline async src="https://www.googletagmanager.com/gtag/js?id=G-********"></script>
<script is:inline>
  window.dataLayer = window.dataLayer || [];
  function gtag() {
    dataLayer.push(arguments);
  }
  gtag("js", new Date());

  gtag("config", "G-********");
</script>

重新部署之后,检查页面上编译后的源码部分,跟复制 Google Analytics 的代码一致,终于可以正常工作了。