# 订阅小组件

**订阅小组件**是一个启动器铃铛加上一个提示，邀请网站访问者订阅推送通知。它将[推送订阅按钮](/zh/developer/pushwoosh-sdk/web-push-notifications/push-subscription-button/)、[自定义订阅弹窗](/zh/developer/pushwoosh-sdk/web-push-notifications/custom-subscription-popup/)和[订阅提示](/zh/developer/guides/messaging-channels/subscription-prompt/)小组件合并为一个组件。启用它后，这三者都不会加载到页面上，因此访问者永远不会看到两个相互竞争的请求。

尚未做出决定的访问者会看到请求。已经屏蔽通知的访问者则会看到关于如何解除屏蔽的说明。

## 前提条件

请确保您已在网站上实现了 Pushwoosh Web SDK 3.0。为此，请遵循我们的[集成指南](/zh/developer/pushwoosh-sdk/web-push-notifications/web-push-sdk-30/#integration)。

## 1. 启用小组件

在 WebSDK 初始化时添加 `subscriptionWidget` 参数，并将 `enable` 设置为 `true`：

```javascript
Pushwoosh.push(['init', {
  //...
  subscriptionWidget: {
    enable: true,
  }
}]);
```

以下每个字段都是可选的。省略的字段将回退到其默认值。在 init 代码段中，超出范围的数字会被静默地限制到最近的边界值，无效的枚举值也会静默地回退到其默认值，且不会有控制台警告。下文所述的 Control Panel 表单会直接拒绝无效值，并拒绝保存。

## 2. 配置提示

```javascript
Pushwoosh.push(['init', {
  //...
  subscriptionWidget: {
    enable: true,
    prompt: {
      layout: 'card',       // 'card' | 'bar' | 'modal'
      position: 'bottom-right',
      iconUrl: 'https://url-image.png',
      borderRadius: 12,     // 0–32
      overlay: false,
    },
    launcher: {
      enabled: true,
      position: 'bottom-right', // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
      offset: 20,           // 0–100
      size: 48,             // 32–80
    },
    display: {
      trigger: 'auto',      // 'auto' | 'launcher' | 'manual'
      delay: 5,             // seconds, 0–3600
      cappingCount: 3,      // auto-shows per visitor, 0–100, 0 = unlimited
      cappingInterval: 24,  // hours between auto-shows, 0–8760
    },
    texts: {
      title: 'Stay in the loop',
      message: 'Get notified about news and updates.',
      acceptText: 'Allow',
      declineText: 'Not now',
      closeText: 'Close',
      blockedTitle: 'Notifications are blocked',
      blockedMessage: 'Enable notifications in your browser settings to stay updated.',
      launcherLabel: 'Subscribe to notifications',
      launcherBlockedLabel: 'Notifications are blocked',
    },
    colors: {
      background: '#ffffff',
      accent: '#4285f4',
      text: '#000000',
      textSecondary: '#666666',
    },
  }
}]);
```

### 布局与位置

`prompt.layout` 设置提示的形状：

- **`card`** —— 锚定在边缘或角落的紧凑卡片。`prompt.position` 接受 `top`、`bottom`、`top-left`、`top-right`、`bottom-left` 或 `bottom-right`。
- **`bar`** —— 横跨页面全宽的横幅。`prompt.position` 仅接受 `top` 或 `bottom`。
- **`modal`** —— 在页面中央显示的窗口。`prompt.position` 始终为 `center`。

在选择位置之前，请先查看上方列表以确认您设置的布局。在 init 代码段中，当前布局不支持的位置会被静默替换为该布局的默认值。Control Panel 表单则会直接拒绝这种组合。

### 何时展示

`display.trigger` 控制什么会打开提示：

- **`auto`** —— 页面加载后 `display.delay` 秒自动打开，此后如果访问者尚未做出决定，则每隔 `display.cappingInterval` 小时再次打开，总共最多 `display.cappingCount` 次（`0` 表示无限制）。
- **`launcher`** —— 仅在访问者点击铃铛时打开。
- **`manual`** —— 仅通过下文所述的 `Pushwoosh.moduleRegistry.subscriptionWidget` 打开。

`display.delay`、`display.cappingCount` 和 `display.cappingInterval` 仅适用于 `auto` 触发方式。

### 启动器铃铛

`launcher.enabled` 会在访问者尚未订阅时显示一个悬浮铃铛，与 `display.trigger` 无关——即使 `trigger` 为 `'auto'`，铃铛也会保持可见，以便访问者在关闭提示后可以重新打开它。`launcher.position` 将其放置在四个角落之一。`launcher.offset`（距边缘的像素偏移）和 `launcher.size`（铃铛的像素直径）用于微调其位置。

### 文本与颜色

一旦浏览器报告访问者已屏蔽通知，`texts.blockedTitle`、`texts.blockedMessage` 和 `texts.closeText` 就会取代请求文本显示——此状态下 `texts.acceptText` 和 `texts.declineText` 永远不会出现。`texts.launcherLabel` 和 `texts.launcherBlockedLabel` 分别是铃铛在两种状态下的提示文字。每个文本字段最多接受 300 个字符。

`colors.accent`、`colors.background`、`colors.text` 和 `colors.textSecondary` 接受十六进制值或 CSS 颜色名称。Control Panel 表单会以这种方式校验每个字段，最多 64 个字符。init 代码段则会接受这些字段的任何非空字符串，而不检查其格式或长度。

<Aside type="note">
深色模式调色板、启动器的 `zIndex` 以及自定义 `fontFamily` 作为仅限 init 参数的附加字段提供。它们不会出现在下文所述的 Control Panel 表单中。
</Aside>

## 在 Control Panel 中管理

<Aside type="caution" title="仅限面板管理的应用">
Control Panel 卡片仅适用于 Web 平台处于**面板管理**模式的应用（参见 [Web Push SDK 3.0](/zh/developer/pushwoosh-sdk/web-push-notifications/web-push-sdk-30/)）。对于代码段配置的应用，请如上所示在 init 代码段中设置 `subscriptionWidget`。
</Aside>

对于面板管理的应用，前往 **Settings → Configure platforms → Web** 并打开 **Subscription widget** 卡片。卡片上的徽章显示小组件当前是 **On** 还是 **Off**。

点击 **Configure** 编辑上文所述的相同字段，这些字段被分组为 **Prompt**、**When to show**、**Bell**、**Texts** 和 **Colors**，旁边是一个实时预览，同时展示未决定访问者和已屏蔽访问者两种状态。保存会替换面板中该小组件配置的副本，不会影响您网站上的 WebSDK init 代码段。

当应用处于面板管理状态时，此卡片中保存的值会覆盖网站 init 代码段中相同的键。将网站切换为面板配置只是面板中的一个开关，网站代码无需改动。

## 3. 从代码中控制小组件

小组件包加载完成后，会在 `Pushwoosh.moduleRegistry.subscriptionWidget` 发布一个 API：

```javascript
Pushwoosh.moduleRegistry.subscriptionWidget.show();          // Opens the prompt
Pushwoosh.moduleRegistry.subscriptionWidget.hide();          // Closes the prompt
Pushwoosh.moduleRegistry.subscriptionWidget.toggle();        // Toggles the current state
Pushwoosh.moduleRegistry.subscriptionWidget.toggle(true);    // Opens the prompt
Pushwoosh.moduleRegistry.subscriptionWidget.isVisible();     // Returns whether the prompt is open
```

对于已经订阅的访问者，`show()` 不起作用。打开提示会触发 `show-subscription-widget` 事件，关闭它会触发 `hide-subscription-widget` 事件：

```javascript
Pushwoosh.addEventHandler('show-subscription-widget', function() {
  console.log('Triggered event: show-subscription-widget');
});

Pushwoosh.addEventHandler('hide-subscription-widget', function() {
  console.log('Triggered event: hide-subscription-widget');
});
```

## 从旧版小组件迁移

只要 `subscriptionWidget.enable` 保持未设置或为 `false`，推送订阅按钮、自定义订阅弹窗和订阅提示就会继续按照各自页面中所述的方式工作。将其设置为 `true` 会同时停止这三者的加载，无论应用是代码段配置还是面板管理。

<Aside type="caution">
将面板管理的应用切换到订阅小组件不会带入它所替代的旧小组件的设置——小组件会从自己的默认值开始，您需要在其卡片中重新进行配置。
</Aside>