# Manifest scope：你的 PWA 安装边界

> scope 字段如何决定应用上下文、深度链接、share_target、shortcuts 与越界导航，以及如何将其与产品设计对齐。

import CompatTable from '@components/CompatTable.astro';

**一句话：** `scope` 是已安装应用的围栏边界。域内 URL 以应用式窗口打开（无地址栏）；
域外 URL 会重新暴露浏览器控件，提示用户已离开应用。`share_target` 与 `shortcuts`
只在域内生效，且 `start_url` 必须落在 scope 之内。

## 为什么 scope 重要

- **分享的链接。** 落在域内的链接保持应用式界面、隐藏地址栏；域外则重新显示地址栏
  ——"你跳到了这个站点的其它页面"——削弱已安装体验。
- **多个已安装应用。** 需要分开发布的产品（如管理端 PWA 与客户端 PWA），当多个
  manifest 的 scope 冲突时会遇到 N+1 安装摩擦。
- **受 scope 绑定的能力。** `share_target` 与 `shortcuts` 只对域内 URL 生效。

## 域内 vs 域外

- **域内**路径以 scope 字符串开头（`/app/` 匹配 `/app/`、`/app/page.html`、
  `/app/dashboard/`）。浏览器控件被抑制。
- **域外**路径（scope 为 `/app/` 时的 `/`、`/blog/`）会再次显示地址栏。
- scope **不会**阻止越界导航——它改变的是呈现方式，不是访问权限。

## 浏览器与生态支持

<CompatTable feature="manifest-scope" />

## 决策判定框架

| 决策问题 | 建议行为 | 理由 |
|---|---|---|
| 想要一个覆盖整站的统一 PWA？ | 省略 `scope`（隐式默认）或设为 `/`。 | 降低 N+1 安装风险；任意深度链接皆"进入应用"。 |
| 需要按字段分别建多个 PWA（管理端 vs 客户端）？ | 每个 manifest 用不同 scope，且各自 `start_url` 落在其 scope 内。 | 每个安装指向独立应用上下文；用户可同时安装两者。 |
| 把 `share_target` 或 `shortcuts` 用作关键能力？ | 声明 `scope` 并验证所有目标/快捷方式 URL 均为域内。 | 这些能力相对 manifest 有界；域外 URL 在已安装时不会正确触发。 |
| 有不属于核心应用的营销/博客页？ | 将 `scope` 设为核心应用路径（`/app/`），营销置于域外并加清晰的"返回应用"导航。 | 用户仍可从明显不同的入口访问营销内容，并预期其显示地址栏。 |
| 深度链接是主要用户流程？ | 将 scope 与所有可深度链接路径的公共最长前缀对齐。 | 保证深度链接的应用内呈现，避免"地址栏再现"。 |

## 实践清单

- [ ] 决定统一 PWA（省略 scope 或 `/`）还是按字段（显式 `/app/`）。
- [ ] 若声明 `scope`，以 `/` 结尾，避免 `/prefix` 同时匹配 `/prefix-of/`。
- [ ] 验证 `start_url` 是 `scope` 的子路径——否则浏览器会回退到基于 `start_url` 的 scope 并忽略你的声明。
- [ ] 确保每个 `share_target` URL 与每个 `shortcuts.url` 都在域内。
- [ ] 在已安装环境测试分享的深度链接：确认域内链接地址栏保持隐藏。
- [ ] 多个 PWA 时，为每个 manifest 设唯一 scope 与各自域内的 `start_url`。

## 这对信任意味着什么

正确范围的 manifest 会让深度链接感觉原生，并让分享与快捷方式可靠地在应用内运作。
看到熟悉的应用式界面（无地址栏）会让用户确认"这条链接属于我已安装的应用"，从而增强
信任。清晰稳定的 scope 也有助于商店评审验证 PWA 的身份：scope 定义了他们在提交时
"预览"的应用内边界。