资讯文章 资讯 · NEWS
让目录站能被添加到主屏:manifest 里真正被检查的字段
2026-10-24 约 2,263 字 预计阅读 6 分钟 yiyunkj
让
Web App Manifest 是一个 JSON 文件,浏览器靠它决定这个站点能不能被当成应用装到设备主屏。装不上的时候没有任何报错,只是安装入口不出现——这让排查变得很烦。
先说一个流传很广的过时说法:安装必须有带 fetch handler 的 service worker。这条在 Chrome 108(安卓)和 Chrome 112(桌面)已经被移除了,现在没有 service worker 也能被安装。不过要注意区分——菜单里的「安装」不再要求 fetch handler,但自动弹出的安装提示(beforeinstallprompt 事件)仍然会检查。另外 Chrome 112 起会忽略空的 fetch handler,写个空函数不算数。

图片来源:网络,版权归原作者所有,侵权请联系删除
Chromium 实际检查的字段
| 字段 | 要求 | 常见错误 |
|---|---|---|
| name 或 short_name | 至少一个 | 两个都没有 |
| icons | 至少 192×192 和 512×512 | 只给了 192 |
| start_url | 必填 | 填了不存在的路径 |
| display | 必须是 standalone / fullscreen / minimal-ui | 写成 browser |
| prefer_related_applications | false 或干脆不写 | 写成 true 导致提示被抑制 |
几个最小可用配置之外的细节:
- HTTPS 是硬条件,测试环境用 localhost 可以,但 staging 域名走 HTTP 不行。
- manifest 要能被取到。放在认证后面的、被 CORS 挡掉的,都会静默失败。
- MIME 类型要对。application/manifest+json 是标准做法,Vercel、Netlify、Cloudflare Pages 这类托管平台对 .webmanifest 会自动加;自建 nginx 需要自己加映射,否则安装提示永远不会触发。
- id 字段建议显式写。不写的话应用身份由 start_url 派生,之后改 start_url 会被当成一个全新的应用,而不是同一次更新。
- background_color 别省,缺了启动时会先白闪一下。
图标:那个 40% 的安全区
安卓从 12 起会把图标裁成圆形、圆角方形或者方圆角形,具体形状取决于设备和启动器。普通图标被裁的时候,启动器会补白边,效果就是 logo 漂在一块白底中间。
解决办法是提供 purpose 为 maskable 的图标变体:安全区是以图标中心为圆心、半径为图标宽度 40% 的圆。重要内容放在中央约 80% 的范围内,外圈当作会被裁掉的出血区。maskable 变体是额外提供,不是替换原有图标。
display_override 是另一个值得用的字段。它接受一个有序列表,浏览器按顺序取第一个支持的:display_override 里可以写 window-controls-overlay,桌面端就能把内容画到标题栏区域。
iOS 完全是另一条路
Safari 不触发 beforeinstallprompt,只能用户自己走「分享 → 添加到主屏幕」。iOS 16.4 起,Chrome、Edge、Firefox 等浏览器也加入了同样的入口。这意味着面向 iPhone 用户,只能做页面内的引导提示,没法用代码触发。
想让添加到主屏后的体验完整一些,还需要 apple-mobile-web-app-capable 和对应的状态栏样式 meta 标签——这部分是苹果自己的私有实现,不在标准 manifest 里。
自定义安装按钮
想自己控制时机,就拦住 beforeinstallprompt 事件:
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
// 显示自己的安装按钮
});
installBtn.addEventListener('click', async () => {
deferredPrompt.prompt();
const { outcome } = await deferredPrompt.userChoice;
deferredPrompt = null;
});
拦下来之后别忘了清理:用完要把引用置空,否则第二次点击会报错。
排查顺序
打开 DevTools 的 Application 面板,选中 Manifest。正常情况下会列出 Identity、Presentation、Icons 三部分;Installability 区域只在有问题的时候才出现,里面列出的是固定的几条错误文案,比如没有 manifest URL、manifest 取不到或解析失败、缺少 name 或 short_name、start_url 无效、display 值不合法。修掉它列出来的那一条,刷新面板再看。
Service Workers 那一栏要显示 activated and is running。注意 DevTools 文档提到过:第一次写入新缓存可能要刷新一次才检测得到,看到缓存列表为空先别急着改代码。
目录站值不值得做
看使用场景。导航站是典型的「高频短时」——用户打开、点一下、走人。装到主屏之后确实少了一步输入或搜索,但收益取决于回访频率。
值得做的情况:用户群里有相当比例是移动端回访用户,且站内提供了「我的收藏」这类个人化功能。
不值得单独为 SEO 做:安装状态和排名没有关系。真正值得做的原因只有一个——缩短老用户的访问路径。
如果决定做,最小投入是先补一份合规的 manifest 加两套图标,这一步成本很低;service worker 的离线缓存另说,那是个独立工程,别为了装得上而顺便上一个写坏的缓存策略。