让它可安装
发布于
完成本指南后,应用会通过 Chrome 的安装标准,只在能响应的浏览器上显示自己的安装按钮,给 iOS 用户提供分享面板路径而不是一个无效按钮,并能在运行时知道自己是否以已安装状态运行。请从一个已经满足入门门槛的站点开始,本指南在其上构建安装体验。
满足 Chrome 的全部标准,包括互动条件
Section titled “满足 Chrome 的全部标准,包括互动条件”web.dev 的 install-criteria 文章列出了 Chrome 触发 beforeinstallprompt 前的检查:应用尚未安装;用户至少点击或轻触过页面一次,并在页面停留至少 30 秒(任何时候都算,包括此前的访问);页面通过 HTTPS 提供;manifest 含 name 或 short_name、192 px 与 512 px 的 icons、start_url、取值为 fullscreen、standalone、minimal-ui 或 window-controls-overlay 的 display,且没有 prefer_related_applications: true。互动条件最常被误认为 bug:在全新的浏览器配置文件里,头半分钟内事件不会触发。把 scope 设成覆盖应用拥有的每条路由;scope 之外的 URL 打开时会带上浏览器界面。
捕获提示并显示自己的按钮
Section titled “捕获提示并显示自己的按钮”在 Chromium 浏览器(Chrome、Edge、Samsung Internet)中,一旦满足标准,浏览器就会触发 beforeinstallprompt。调用 preventDefault() 抑制移动端浏览器自带的横幅,保留事件并显示按钮。prompt() 解析出的 outcome 为 "accepted" 或 "dismissed"(MDN,BeforeInstallPromptEvent.userChoice),而被延迟的事件只能 prompt 一次:
let deferredPrompt = null;const installButton = document.querySelector('#install');
window.addEventListener('beforeinstallprompt', (event) => { event.preventDefault(); deferredPrompt = event; installButton.hidden = false;});
installButton.addEventListener('click', async () => { if (!deferredPrompt) return; const { outcome } = await deferredPrompt.prompt(); deferredPrompt = null; installButton.hidden = true; if (outcome === 'dismissed') { localStorage.setItem('install-dismissed-at', String(Date.now())); }});
window.addEventListener('appinstalled', () => { installButton.hidden = true; deferredPrompt = null;});按钮初始隐藏,在从不触发该事件的 Firefox 与 Safari 上保持隐藏(MDN 将该事件列为非 Baseline)。当用户通过浏览器菜单而非你的按钮安装时,appinstalled 监听器同样会隐藏按钮。在用户做出表明意图的动作之后再显示按钮,例如保存第二条记录;首屏即弹出的提示是在应用展示任何价值之前就索要承诺,而记录拒绝时间戳可以让你等一周再问。
给 iOS 用户分享面板的说明
Section titled “给 iOS 用户分享面板的说明”iOS 与 iPadOS 上的 Safari 没有 beforeinstallprompt,路径是 Share 按钮,然后 Add to Home Screen(英文界面),WebKit 的 Web Push 公告如此描述。MDN 指出自 iOS 16.4 起,iOS 上的 Chrome、Edge、Firefox 与 Orion 的分享菜单也有同一入口。检测平台与 standalone 状态,然后显示说明而不是按钮:
const isIos = /iphone|ipad|ipod/i.test(navigator.userAgent) && !window.MSStream;const isStandalone = window.matchMedia('(display-mode: standalone)').matches || navigator.standalone === true;
if (isIos && !isStandalone) { document.querySelector('#ios-install-hint').hidden = false; // 「点 Share,再点 Add to Home Screen」}navigator.standalone 是 Safari 独有、表示主屏幕 Web 应用的属性;display-mode 媒体查询是跨浏览器的检测,也是 web.dev customize-install 文章中 getPWADisplayMode() 辅助函数所用的方法。
逐条路径验证
Section titled “逐条路径验证”桌面版 Chrome 在满足标准的页面上会在地址栏右侧显示安装图标;菜单路径是 More > Cast, save, and share > Install page as app…(英文界面,Chrome 帮助)。Android 上的路径是 More > Install and create shortcut > Install。安装后启动应用,在控制台确认 matchMedia('(display-mode: standalone)').matches 为 true,且安装按钮已隐藏。要从干净状态重测,在已安装窗口里走 More > Uninstall [app name] > Remove 卸载。
- 入门
- 安装提示
- iOS 添加到主屏幕
- 安装提示兼容性
- How to provide your own in-app install experience(web.dev)
- Installation criteria(web.dev)
← 返回指南总览。