---
title: "Google Tag Manager"
description: "加载 GTM Web 容器，并从 Nuxt 推送页面或同意事件。"
canonical_url: "https://nuxt-scripts.zhcndoc.com/scripts/google-tag-manager"
last_updated: "2026-08-11T09:33:11.102Z"
---

[Google Tag Manager](https://marketingplatform.google.com/about/tag-manager/) 从 Web 容器加载标签，让你无需重新部署应用即可更改跟踪配置。

<callout>

GTM 可以加载容器中配置的任何标签，因此其性能开销会因配置而异。如果你只需要 Google Analytics，[`useScriptGoogleAnalytics()`](/scripts/google-analytics) 组合式函数可能更简单。

</callout>

<callout icon="i-heroicons-information-circle">

Nuxt Scripts 只加载 GTM **容器**。跟踪功能来自 GTM 工作区中的标签和触发器，或来自你自己的 `dataLayer.push` 调用。若要自动跟踪页面、点击、滚动和视频，请为 GA4 Web 数据流启用 [GA4 增强型衡量](https://support.google.com/analytics/answer/9216061)。

</callout>

<script-stats>



</script-stats>

<script-docs>



</script-docs>

### 发送页面事件

将代理与 [`useScriptEventPage()`](/docs/api/use-script-event-page) 配合使用，在 Nuxt 完成初始客户端渲染或后续路由更改并更新页面标题后推送事件：

```ts
const { proxy } = useScriptGoogleTagManager({
  id: 'YOUR_ID' // 仅当你未全局配置时需要提供 id
})

useScriptEventPage(({ title, path }) => {
  // 在较早注册时对初始渲染运行，之后对路由更改运行。
  proxy.dataLayer.push({
    event: 'pageview',
    title,
    path
  })
})
```

## 同意模式

Google Tag Manager 接受 [GCMv2 同意状态](https://developers.google.com/tag-platform/security/guides/consent?consentmode=basic)。`defaultConsent` 会在 `gtm.js` 事件之前进入队列；对于后续选择，请使用 `consent.update()`。如果初始默认值由客户端状态决定，请在调用组合式函数之前解析该状态，并通过 `defaultConsent` 传入。初始化后调用 `consent.default()` 会在队列中加入另一个默认值，因此无法复现原始的顺序。

<callout icon="i-heroicons-play" target="_blank" to="https://stackblitz.com/github/nuxt/scripts/tree/main/examples/cookie-consent">

在 [StackBlitz](https://stackblitz.com) 上打开[Cookie 同意](https://stackblitz.com/github/nuxt/scripts/tree/main/examples/cookie-consent)、[细粒度同意](https://stackblitz.com/github/nuxt/scripts/tree/main/examples/granular-consent)或[区域同意](https://stackblitz.com/github/nuxt/scripts/tree/main/examples/regional-consent)示例。

</callout>

### 同意模式 v2 信号

<table>
<thead>
  <tr>
    <th>
      信号
    </th>
    
    <th>
      目的
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        ad_storage
      </code>
    </td>
    
    <td>
      广告相关的 Cookie
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ad_user_data
      </code>
    </td>
    
    <td>
      向 Google 发送用户数据用于广告
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ad_personalization
      </code>
    </td>
    
    <td>
      个性化广告（再营销）
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        analytics_storage
      </code>
    </td>
    
    <td>
      分析相关的 Cookie
    </td>
  </tr>
</tbody>
</table>

### 示例

```vue
<script setup lang="ts">
const { proxy, consent } = useScriptGoogleTagManager({
  id: 'GTM-XXXXXX',
  defaultConsent: {
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    analytics_storage: 'denied',
  },
})

function acceptAll() {
  consent.update({
    ad_storage: 'granted',
    ad_user_data: 'granted',
    ad_personalization: 'granted',
    analytics_storage: 'granted',
  })
}

function savePreferences(choices: { analytics: boolean, marketing: boolean }) {
  consent.update({
    analytics_storage: choices.analytics ? 'granted' : 'denied',
    ad_storage: choices.marketing ? 'granted' : 'denied',
    ad_user_data: choices.marketing ? 'granted' : 'denied',
    ad_personalization: choices.marketing ? 'granted' : 'denied',
  })
}

useScriptEventPage(({ title, path }) => {
  proxy.dataLayer.push({ event: 'pageview', title, path })
})
</script>
```

### 按地区的默认值

将一个数组传递给 `defaultConsent`，即可按照输入顺序为每个条目加入一条默认同意命令。这与 Google 的[特定区域同意模式](https://developers.google.com/tag-platform/security/guides/consent?consentmode=advanced#region-specific-behavior)一致：更具体的区域（例如 `US-CA`）会覆盖更宽泛的区域（`US`）；不包含 `region` 的条目是无作用域的全局回退值。

```vue
<script setup lang="ts">
useScriptGoogleTagManager({
  id: 'GTM-XXXXXX',
  defaultConsent: [
    {
      // 欧洲经济区 + 英国 + 瑞士：初始设为拒绝，并等待 500 毫秒获取选择。
      ad_storage: 'denied',
      ad_user_data: 'denied',
      ad_personalization: 'denied',
      analytics_storage: 'denied',
      region: ['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB', 'IS', 'LI', 'NO', 'CH'],
      wait_for_update: 500,
    },
    {
      // 其他所有地区：默认授予。
      ad_storage: 'granted',
      ad_user_data: 'granted',
      ad_personalization: 'granted',
      analytics_storage: 'granted',
    },
  ],
})
</script>
```

该模块会按输入顺序逐项原样转发。区域限定与非限定默认值之间的优先级由运行时的 gtag 决定，而不是由顺序决定。

`consent.update()` 和 `consent.default()` 都接受任意 `Partial<ConsentState>`；缺失的类别会保持其当前值。两种方法都会根据规范的 GCMv2 schema 验证输入，并在遇到未知键或非 `granted`/`denied` 值时通过 `consola` 发出警告。`onBeforeGtmStart` 仍然可用，作为任何其他 `gtm.start` 之前设置的通用逃生舱口（仅当 GTM ID 直接传递给组合式函数时可用，而不是通过 `nuxt.config` 传入时）。

<script-types>



</script-types>

## 示例

### 服务端 GTM

使用[服务端标记](https://developers.google.com/tag-platform/tag-manager/server-side/intro)时，Web 容器仍在浏览器中运行，并将测量请求发送到由您运营的服务器容器。将每个受支持标记的传输网址（例如 Google 标记中的 `server_container_url`）设置为服务器容器；仅更改 GTM 加载器网址不会重新路由这些请求。

前提条件包括一个[服务端 GTM 容器](https://tagmanager.google.com)、[Cloud Run](https://developers.google.com/tag-platform/tag-manager/server-side/cloud-run-setup-guide) 等托管服务或[手动部署](https://developers.google.com/tag-platform/tag-manager/server-side/manual-setup-guide)，以及一个[自定义域名](https://developers.google.com/tag-platform/tag-manager/server-side/custom-domain)。

#### 配置

如果您配置的第一方标记域名提供 Web 容器加载器，请覆盖源地址并保留容器 ID 查询参数：

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  scripts: {
    registry: {
      googleTagManager: {
        id: 'GTM-XXXXXX',
        trigger: 'onNuxtReady',
        scriptInput: {
          src: 'https://analytics.example.com/gtm.js?id=GTM-XXXXXX'
        }
      }
    }
  }
})
```

此源地址覆盖仅会更改浏览器加载 `gtm.js` 的位置。请按照 Google 的[服务端标记文档](https://developers.google.com/tag-platform/tag-manager/server-side)配置 Web 容器和服务器容器，将测量请求路由到服务器容器。
