---
type: how-to
title: 客户端集成
summary: 如何把组件放到你的页面上，通过 CDN script 标签或 npm 导入，以及该用哪一种。
---

组件是一个小小的包，`@caputchin/widget`，它会注册 `<caputchin-widget>` 和 `<caputchin-game>` 自定义元素。把它放到你页面上有两种方式。按你的站点有没有构建步骤来选。

<Callout type="warn">
当一个密钥要求游戏时，这两个元素不可互换。如果一个站点密钥打开了游戏关卡（它的 **要求一个游戏来验证** 设置），那么复选框式的 `<caputchin-widget>` 无法在它上面通过，并会抛出一个 `gate-unavailable` 错误；只有 `<caputchin-game>` 在那里能用。这是有意为之的，因为关卡是在 Caputchin 这一侧强制执行的。见 [游戏关卡](/docs/site-keys/games)。
</Callout>

## Script 标签（CDN）

没有构建步骤，一个纯 HTML 或服务端渲染的页面？直接从 jsDelivr CDN 加载它：

```html
<script src="https://cdn.jsdelivr.net/npm/@caputchin/widget@3/dist/widget.js"></script>
```

那个 `@3` 把当前的主版本钉住，于是你拿到修复和新游戏，而不会冒出意外的破坏性变更。把那一行放进你的 `<head>`（或就在 `</body>` 之前），元素就为整个页面注册好了。

## npm（ESM）

有一个打包器（Vite、webpack、Next.js 等等）？安装这个包，并在启动时导入它一次：

```bash
npm install @caputchin/widget
```

```js
import "@caputchin/widget";
```

这个导入不暴露任何可调用的东西；它运行是为了它注册自定义元素的副作用。把它放在你的应用入口里，让它在任何 `<caputchin-widget>` 渲染之前运行。

## 用哪一个？

- **没有构建步骤**（纯 HTML，一个服务端渲染的模板）：用 **script 标签**。它就是一行里的整套集成。
- **一个打包后的应用**（React、Vue 以及其余）：用 **npm 导入**。它随你的 lockfile 一起版本化，并避免一个阻塞渲染的外部请求。

无论哪种方式，元素以及下游的一切（注入的令牌、你的服务器检查）都完全相同。唯一改变的，是这个包如何到达。

## 另见

- [前端集成示例](/docs/integration-guides/frontend-examples)，看这个元素在各个框架里的样子。
- [把组件添加到你的站点](/docs/getting-started/add-the-widget)，看完整的演练。
