# Firefox 上的 PWA

> Firefox 上的安装意味着什么：Firefox 143 起 Windows 支持任务栏 Web 应用，Firefox for Android 可按 manifest 安装，两者都没有 beforeinstallprompt。

Firefox 只在两个地方安装 Web 应用：Windows 上的 Firefox 143 及之后版本可以把网站固定到任务栏并在简化窗口中运行；Firefox for Android 可以从菜单把带 manifest 的网站添加到主屏幕。两条路径都不会触发 `beforeinstallprompt`，为 Chromium 写的安装流程代码必须分支处理。

## 工作原理

Firefox 没有 Chromium 式的地址栏安装图标，也没有页面内的安装事件。实际存在的是一个只在一种操作系统上提供的桌面功能和一个移动端功能，都从 Firefox 自己的界面进入。

### Windows 上的任务栏 Web 应用（Firefox 143+）

[Firefox 143.0 发行说明](https://www.firefox.com/en-US/firefox/143.0/releasenotes/)（2025-09-16）把该功能描述为"把网站作为 Web 应用直接固定到任务栏运行"：用户固定网站后，它从任务栏启动、在简化窗口中打开，并保留用户已安装的附加组件。发行说明同时排除了从 Microsoft Store 安装的 Firefox，且该版本只支持 Windows。流程不是由网站的 manifest 发起，而是由用户从地址栏发起。

### Firefox for Android 上的主屏幕 Web 应用

Android 上走菜单。Mozilla 的支持文章 [Use Web Apps with Firefox for Android](https://support.mozilla.org/en-US/kb/use-web-apps-firefox-android) 给出步骤：打开网站，点按菜单按钮，点按 **Install**，随后出现 Android 的 **Add to Home Screen** 面板，用户可以把图标拖到想要的位置，或点按 **Add automatically**（英文界面）。图标在 Firefox 中打开网站；卸载 Firefox 会一并删除该 Web 应用。

### macOS 与 Linux 上的桌面版 Firefox

Firefox 143 在 macOS 和 Linux 上没有由 manifest 驱动的安装流程。MDN 的[安装指南](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Installing)指出，桌面版 Firefox 需要第三方 PWA 扩展才能安装网站。对这些用户诚实的建议是收藏书签或使用普通标签页，而应用必须在普通标签页中完整可用。

### Firefox 没有实现的部分

`BeforeInstallPromptEvent` 不是标准，[MDN 未列出任何实现它的 Firefox 或 Firefox for Android 版本](https://developer.mozilla.org/en-US/docs/Web/API/BeforeInstallPromptEvent)（Chrome 44+、Edge 79+、Samsung Internet 4.0+ 有实现）。页面在 Firefox 上无法推迟、触发或检测安装提示，`appinstalled` 也不会触发。

## 示例

两个示例在 Chromium 浏览器中原样运行；分支是为 Firefox 和 Safari 准备的。

### 只在事件触发后显示安装按钮

提供"安装应用"按钮的代码必须检测事件是否存在，而不是假设它存在，并且要在没有该事件的浏览器上给出有用的说明。

```html
<button id="install-button" hidden>安装应用</button>
<p id="install-instructions" hidden>
  这个浏览器不支持从页面一键安装。可以直接当作标签页使用，或收藏为书签。
  在 Firefox for Android 上，打开菜单并点按 Install。
</p>

<script>
  let deferredPrompt = null;
  const installButton = document.getElementById('install-button');
  const installInstructions = document.getElementById('install-instructions');

  if (!('onbeforeinstallprompt' in window)) {
    // Firefox（任何系统）与 Safari：这里不存在该事件。
    installInstructions.hidden = false;
  } else {
    window.addEventListener('beforeinstallprompt', (event) => {
      event.preventDefault();
      deferredPrompt = event;
      installButton.hidden = false;
    });

    installButton.addEventListener('click', async () => {
      if (!deferredPrompt) return;
      deferredPrompt.prompt();
      deferredPrompt = null;
    });
  }
</script>
```

`'onbeforeinstallprompt' in window` 是属性检测，在任何事件有机会触发之前就能工作；如果等待事件本身，Firefox 上的回退说明会一直隐藏。

### 检测简化窗口

只要 manifest 请求了 `standalone`，Firefox 任务栏 Web 应用和 Firefox for Android 主屏幕 Web 应用都会报告 `display-mode: standalone`，与 Chromium 和 WebKit 使用同一个媒体特性。

```js
function runsAsInstalledApp() {
  if (typeof window.matchMedia !== 'function') {
    // 没有 matchMedia：当作普通标签页处理。
    return false;
  }
  return window.matchMedia('(display-mode: standalone)').matches;
}

document.body.dataset.installed = runsAsInstalledApp() ? 'yes' : 'no';
```

用它在已安装窗口内隐藏安装提示即可；不要用它限制功能，同一个用户下一次可能在普通标签页里打开网站。

## 实测行为

Windows 上的这项功能由一个默认开启的首选项控制，这也是隐藏其地址栏入口唯一有文档记载的方式。

:::observed
Windows 11 上的 Firefox 143（英文界面）：`about:config` 中 `browser.taskbarTabs.enabled` 默认值为 `true`，普通网站的地址栏会出现 "Add tab to taskbar" 图标。把该首选项改为 `false` 后图标消失，见 Mozilla Support 讨论串 [How can two icons … be removed from the address bar?](https://support.mozilla.org/en-US/questions/1534646)（support.mozilla.org）。
:::

由于固定窗口保留附加组件（发行说明，2025-09-16），内容拦截器和密码管理器在 Web 应用里继续工作；在假设某个第三方脚本能在那里加载之前，先开着拦截器测一遍。

## 另请参阅

- [Chrome 与 Android 上的 PWA](/zh/reference/platforms/chrome-android/)
- [iOS 与 Safari 上的 PWA](/zh/reference/platforms/ios-safari/)
- [安装提示](/zh/reference/installation/install-prompt/)
- [安装提示兼容性](/zh/compatibility/install-prompt/)
- [Firefox 143.0 release notes](https://www.firefox.com/en-US/firefox/143.0/releasenotes/)（firefox.com）
- [Use Web Apps with Firefox for Android](https://support.mozilla.org/en-US/kb/use-web-apps-firefox-android)（support.mozilla.org）
- [BeforeInstallPromptEvent](https://developer.mozilla.org/en-US/docs/Web/API/BeforeInstallPromptEvent)（developer.mozilla.org）