Platform in Platforms
PWAs on Meta Quest (Horizon OS browser)
Published Updated
Meta Horizon OS supports web-based 2D experiences that can be distributed through the Meta Horizon Store. Meta documents Bubblewrap as the tool that packages a PWA into an Android App Bundle and launches its web content through a Trusted Web Activity (Start Building with Meta Quest 3S, Meta Horizon OS Developers).
Platform support
Section titled “Platform support”Meta documents Meta Horizon Store distribution for web-based 2D experiences on Meta Horizon OS. For immersive features, MDN marks XRSystem.isSessionSupported() as limited availability and available only in secure contexts in supporting browsers; the method checks whether the user’s WebXR device supports a requested session mode (Start Building with Meta Quest 3S, Meta Horizon OS Developers; XRSystem: isSessionSupported() method, MDN).
How it works
Section titled “How it works”A Trusted Web Activity opens PWA content from an Android app through a protocol based on Custom Tabs. Digital Asset Links verify that the Android app and the site come from the same developer, while the user’s browser renders the web content (Trusted Web Activity overview, Chrome for Developers).
Examples
Section titled “Examples”The example keeps ordinary page content available unless the browser reports support for an immersive VR session.
Reveal an immersive control after checking support
Section titled “Reveal an immersive control after checking support”Paste this complete page into an HTTPS origin. It checks for navigator.xr, handles both the unsupported and rejected paths, and leaves the non-immersive content visible.
<!doctype html><html lang="en"> <body> <p>This content works without an immersive session.</p> <button id="enter-xr" hidden>Enter XR</button> <output id="xr-status">Checking WebXR support...</output> <script> const button = document.querySelector('#enter-xr'); const status = document.querySelector('#xr-status');
if (!('xr' in navigator)) { status.value = 'Continue without immersive mode.'; } else { navigator.xr.isSessionSupported('immersive-vr').then((supported) => { button.hidden = !supported; status.value = supported ? 'Immersive mode is available.' : 'Continue without immersive mode.'; }).catch(() => { button.hidden = true; status.value = 'Continue without immersive mode.'; }); } </script> </body></html>The button remains hidden when navigator.xr is absent, the requested session mode is unsupported, or the support check rejects.
Read launch data from the URL
Section titled “Read launch data from the URL”A Trusted Web Activity host can pass data to its web content in a URL, including through query parameters (Trusted Web Activity overview, Chrome for Developers). Save this page as launch.html, then open launch.html?source=quest.
<!doctype html><html lang="en"> <body> <output id="launch-source">No launch source supplied.</output> <script> const source = new URLSearchParams(location.search).get('source'); if (source) { document.querySelector('#launch-source').value = `Launched from ${source}.`; } </script> </body></html>The output reads Launched from quest. when the query parameter is present and retains the fallback text when it is absent.
See also
Section titled “See also”- Manifest scope
- Installable PWAs
- Start Building with Meta Quest 3S (Meta Horizon OS Developers)
- Trusted Web Activity overview (Chrome for Developers)
- XRSystem: isSessionSupported() method (MDN)
Specifications
| Specification | Status |
|---|---|
| None. | |