# 增强安装界面

> Chrome 如何把安装提示变成带 description 与 screenshots 的面板，截图尺寸、宽高比与 form_factor 规则，以及部署前如何检查 manifest。

增强安装界面（richer install UI）是 Chrome 更大的安装对话框，在名称与图标之外还显示 manifest 的 `description` 与 `screenshots`，而默认对话框只显示名称与图标。Android 上的 Chrome 94 在 manifest 具有 `description` 且至少一张截图时以底部面板显示它；桌面端 Chrome 108 在至少一张截图带有 `form_factor: "wide"` 时显示它；Samsung Internet 17 跟随 Chrome for Android；Safari 与 Firefox 不会为任何安装界面解析这两个成员（BCD `html.manifest.screenshots`、`html.manifest.description`）。

## 工作原理

对话框在发起提示时选定，无论提示来自浏览器自己的入口还是 `BeforeInstallPromptEvent.prompt()`。Chrome 读取它为可安装性检查已抓取的 manifest，按当前设备形态过滤 `screenshots`，过滤后为空则回退到默认对话框。页面的 JavaScript 无法请求、也无法检测出现的是哪种对话框；两种情况下 `userChoice` 的兑现方式相同。

Chrome 在计入每张截图之前都会执行这些规则：

- 宽和高都在 320 px 到 3840 px 之间。
- 长边最多为短边的 2.3 倍。
- 一起显示的所有截图必须共享同一宽高比；第一张截图决定比例，不匹配的会被丢弃。
- 桌面端只使用 `form_factor: "wide"` 的截图；Android 使用 `form_factor: "narrow"` 或未设置 `form_factor` 的截图。
- 存在 `sizes` 与 `type` 时会读取；加载失败的截图会被跳过。

Chrome 还限制显示的截图数量，桌面端可能截断过长的 `description`，所以第一句话必须把意思说完。这两个成员是声明式的：已安装的应用在运行时从不读取它们，修改它们只会改变下一次的安装对话框（以及在 Chrome 周期性更新 manifest 之后应用的商店式详情页）。

:::observed
在 Chrome DevTools › Application › Manifest（英文界面）中，若所有截图都没有 `form_factor: "wide"`，"Installability" 标题下会出现警告 `Richer PWA Install UI won't be available on desktop. Please add at least one screenshot with the form_factor set to wide.`；若只有 wide 截图，则显示对应的移动端提示，要求补一张 `form_factor` 不是 `wide` 的截图。桌面端这条规则正是 Chrome 关于桌面增强安装界面公告中描述的那条。
:::

## 示例

manifest 片段同时满足两种对话框；脚本则在部署前检查 DevTools 只会在事后报告的那些规则。

### 一份同时满足 Android 与桌面端对话框的 manifest

narrow 截图共享 9:16 的比例，服务于 Android；wide 截图服务于桌面端。每张都带 `sizes`，Chrome 不必解码图片就能应用比例规则。

```json
{
  "name": "Meal Planner",
  "description": "Plan a week of meals, build the shopping list, and cook offline.",
  "screenshots": [
    { "src": "/screenshots/week.png", "sizes": "1080x1920", "type": "image/png",
      "form_factor": "narrow", "label": "Weekly plan" },
    { "src": "/screenshots/list.png", "sizes": "1080x1920", "type": "image/png",
      "form_factor": "narrow", "label": "Shopping list" },
    { "src": "/screenshots/desktop.png", "sizes": "1920x1080", "type": "image/png",
      "form_factor": "wide", "label": "Weekly plan on a large screen" }
  ]
}
```

去掉 `wide` 那一项，Android 面板保留，桌面端用户则悄悄回到默认对话框；把 1080×1920 与 1080×2340 的 narrow 截图混在一起，只有与第一项比例一致的会被保留。

### 部署前按规则检查 manifest

没有运行时 API 能检测增强对话框，所以有用的检查是一个部署前脚本，报告与 Chrome 相同的条件。用 Node 对构建产物中的 manifest 运行它，不需要浏览器。

```js
import { readFile } from 'node:fs/promises';

const manifest = JSON.parse(await readFile('dist/manifest.webmanifest', 'utf8'));
const shots = manifest.screenshots ?? [];
const problems = [];

if (!manifest.description) problems.push('缺少 description：Android 将显示默认对话框');
if (!shots.some((s) => s.form_factor === 'wide')) problems.push('没有 wide 截图：桌面端将显示默认对话框');
for (const s of shots) {
  const [w, h] = (s.sizes ?? '').split('x').map(Number);
  if (!w || !h) { problems.push(`${s.src}：请补充 sizes 以便检查比例规则`); continue; }
  if (w < 320 || h < 320 || w > 3840 || h > 3840) problems.push(`${s.src}：${w}x${h} 超出 320-3840`);
  if (Math.max(w, h) / Math.min(w, h) > 2.3) problems.push(`${s.src}：宽高比超过 2.3`);
}
console.log(problems.length ? problems.join('\n') : '截图通过增强安装界面规则');
```

通过了这个脚本的 manifest，仍可能因为某张图片在提示时返回非图片响应而回退到默认对话框，所以截图 URL 应与 manifest 放在同一次部署里。

## 另请参阅

- [Richer install UI for desktop](https://developer.chrome.com/blog/richer-install-ui-desktop)（developer.chrome.com）
- [Web App Manifest Application Information: screenshots member](https://w3c.github.io/manifest-app-info/#screenshots-member)（w3c.github.io）
- [`screenshots` manifest 成员](/zh/reference/manifest/screenshots/)
- [`description` manifest 成员](/zh/reference/manifest/description/)
- [beforeinstallprompt 事件](/zh/reference/installation/install-prompt/)
- [安装提示 UX](/zh/reference/installation/install-prompt-ux/)