---
title: "注册表脚本"
description: "配置、复用和扩展来自 Nuxt Scripts 注册表的类型化集成。"
canonical_url: "https://nuxt-scripts.zhcndoc.com/docs/guides/registry-scripts"
last_updated: "2026-08-11T09:33:07.165Z"
---

注册表脚本是针对常见第三方服务预配置的集成。在[脚本注册表](/scripts)中浏览可用的集成。

许多第三方脚本需要在加载脚本前初始化一些全局状态，Nuxt 脚本会以优化的方式帮你处理这一过程。

### 安全初始化

注册表组合式函数会在添加外部脚本之前初始化所需的全局状态。

### 加载控制

每个注册表条目都会声明其支持的打包、代理和 Partytown 功能。由组合式函数驱动的集成还支持加载触发器。

### 类型

注册表脚本包含其配置和公开 API 的类型，因此编辑器可以补全诸如 `gtag()` 这样的调用，而无需单独声明全局变量。

### 开发时验证

注册表脚本使用 [Valibot schemas](https://valibot.dev/guides/schemas/) 在开发期间验证配置。例如，Cloudflare Web Analytics schema 会拒绝长度少于 32 个字符的令牌。

<code-group>

```ts [Schema]
export const CloudflareWebAnalyticsOptions = object({
  /**
   * Cloudflare Web Analytics 的令牌。
   */
  token: pipe(string(), minLength(32)),
  /**
   * Cloudflare Web Analytics 通过重写 History API 的 pushState 函数和监听 onpopstate 自动测量 SPA。
   * 不支持基于哈希的路由器。
   *
   * @default true
   */
  spa: optional(boolean()),
})
```

```ts [示例]
useScriptCloudflareWebAnalytics({
  token: '123', // 由于令牌过短，在开发环境中跳过
})
```

</code-group>

生产构建会移除验证代码。在开发期间，Nuxt Scripts 会跳过无效脚本，并记录 schema 问题。

### 运行时配置

在 `nuxt.config.ts` 中注册脚本，Nuxt Scripts 会为该集成声明的、由环境变量提供的输入创建公开运行时配置字段。然后，你可以通过 `.env` 提供其 ID 或令牌等字段，而不是将它们硬编码。

<code-group>

```text [.env]
NUXT_PUBLIC_SCRIPTS_CLOUDFLARE_WEB_ANALYTICS_TOKEN=YOUR_TOKEN
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  scripts: {
    registry: {
      cloudflareWebAnalytics: { trigger: 'client' },
    },
  },
})
```

</code-group>

## 使用

### 在开发环境中禁用

当开发代码调用 `gtag` 等 API，但不希望加载供应商脚本时，将注册表条目设置为 `mock`。模拟模式会注册一个手动上下文，并跳过选项验证。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  scripts: {
    registry: {
      googleTagManager: { trigger: 'onNuxtReady' },
    },
  },
  $development: {
    scripts: {
      registry: {
        googleTagManager: 'mock',
      },
    },
  },
})
```

### 加载多个实例

注册表脚本会根据 `src` 或 `key` 去重。当需要使用具有不同配置的多个实例时，请为每次调用设置唯一的 `key`。

```ts
const { proxy: gaOne } = useScriptGoogleAnalytics({
  id: 'G-TR58L0EF8P',
})

const { proxy: gaTwo } = useScriptGoogleAnalytics({
  // 不设置 key 会返回第一个脚本实例
  key: 'gtag2',
  id: 'G-1234567890',
})
```

自定义 key 也会更改运行时配置路径。对于 `key: 'gtag2'`，请自行声明匹配的路径：

```ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      scripts: {
        gtag2: {
          id: '', // NUXT_PUBLIC_SCRIPTS_GTAG2_ID
        },
      },
    },
  },
})
```

### 使用脚本选项和脚本输入

注册表脚本通过以下两个字段公开核心 [`useScript()`](/docs/api/use-script) 输入：

- `scriptOptions`：[useScript 选项](/docs/api/use-script#nuxtusescriptoptions)，例如 `trigger`。
- `scriptInput`：[脚本元素输入](/docs/api/use-script#usescriptinput)，例如 `data-*` 属性。

```ts
import { useTimeout } from '@vueuse/core'
import { useScriptGoogleAnalytics } from '#imports'

const ready = useTimeout(5000)
useScriptGoogleAnalytics({
  id: 'G-XXXXXXXX',
  // 要传递给脚本元素的 HTML 属性
  scriptInput: {
    'data-test': 'true',
  },
  // 用于高级功能的 useScript 选项
  scriptOptions: {
    trigger: ready,
  },
})
```

### 重用一个实例

如果多个页面使用相同的集成，请在 `app.vue` 或 `nuxt.config` 中配置一次。之后的组合式函数调用会返回该脚本实例，无需再次传入选项。

<code-group>

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  scripts: {
    registry: {
      // 显式触发器会在全局加载脚本。
      fathomAnalytics: {
        site: 'SITE_ID',
        trigger: 'onNuxtReady',
      }
    }
  }
})
```

```vue [components/any-component.vue]
<script setup lang="ts">
const { proxy } = useScriptFathomAnalytics() // 不需要传入选项
</script>

<template>
  <button @click="proxy.trackGoal('GOAL_ID', 0)">
    跟踪目标
  </button>
</template>
```

</code-group>

你也可以将共享配置保留在自己的组合式函数中：

```ts
export function useFathomAnalytics() {
  return useScriptFathomAnalytics({
    site: 'SITE_ID',
  })
}
```

## 扩展脚本注册表

使用 `nuxt.config.ts` 中的 `scripts:registry` 钩子来添加集成：

```ts [nuxt.config.ts]
import { createResolver } from '@nuxt/kit'

const { resolve } = createResolver(import.meta.url)

export default defineNuxtConfig({
  modules: ['@nuxt/scripts'],

  hooks: {
    'scripts:registry': function (registry) {
      registry.push({
        category: 'custom',
        label: '我的自定义分析',
        logo: '<svg>...</svg>', // 可选
        import: {
          name: 'useScriptMyAnalytics',
          from: resolve('./composables/useScriptMyAnalytics'),
        },
      })
    },
  },

  devtools: {
    enabled: true,
  },
})
```

然后创建你的自定义脚本 composable：

```ts [composables/useScriptMyAnalytics.ts]
import type { RegistryScriptInput } from '#nuxt-scripts/types'
import { object, string } from 'valibot'
import { useRegistryScript } from '#nuxt-scripts/utils'

export interface MyAnalyticsApi {
  track: (event: string, data?: Record<string, any>) => void
  identify: (userId: string) => void
}

declare global {
  interface Window {
    MyAnalytics: MyAnalyticsApi & { init: (apiKey?: string) => void }
  }
}

// 用于验证和 DevTools 元数据的 Schema
export const MyAnalyticsSchema = object({
  apiKey: string(),
})

export type MyAnalyticsInput = RegistryScriptInput<typeof MyAnalyticsSchema>

export function useScriptMyAnalytics<T extends MyAnalyticsApi>(options?: MyAnalyticsInput) {
  return useRegistryScript<T, typeof MyAnalyticsSchema>('myAnalytics', resolvedOptions => ({
    scriptInput: {
      src: 'https://analytics.example.com/sdk.js',
    },
    schema: import.meta.dev ? MyAnalyticsSchema : undefined,
    scriptOptions: {
      ...options?.scriptOptions,
      use() {
        if (!window.MyAnalytics)
          return
        window.MyAnalytics.init(resolvedOptions.apiKey)
        return window.MyAnalytics as T
      },
    },
  }), options)
}
```

### 使用自定义注册表脚本

Nuxt 会自动导入已注册的 composable：

```vue [pages/index.vue]
<script setup lang="ts">
// 从你的注册表自动导入
const { proxy, status } = useScriptMyAnalytics({
  apiKey: 'your-api-key',
  scriptOptions: {
    trigger: 'onNuxtReady'
  }
})

// 使用脚本 API
function trackClick() {
  proxy.track('button_click', { button: 'hero-cta' })
}
</script>

<template>
  <button @click="trackClick">
    跟踪此点击
  </button>
  <div>状态：{{ status }}</div>
</template>
```

### DevTools 集成

当你包含验证 Schema 时，Nuxt Scripts 会在开发环境中使用其中的必填字段来填充脚本的 DevTools 元数据。
