Published: May 12, 2026
Installing web apps has always required JavaScript. When you use the
beforeinstallprompt event, the installation flow lives entirely in script. The
new <install> element changes that: drop a single HTML element into your page
and the browser renders a trusted install button for you, with no JavaScript
required.

The Microsoft Edge team, in collaboration with the Chrome team, implemented the
<install> element in Chromium. It's now available for you to test
behind a flag in Chrome or Edge from version 148, and as an
origin trial
which you can use in both browsers starting with 148 and ending with 153.
Try it, and learn how it compares to the imperative Web Install
API
(navigator.install()), which has its own origin
trial.
The problem
Web app installation is fragmented. Every browser has its own set of entry points, for example address-bar icons, menu items, and prompts. Developers have limited control over when and how the install flow is surfaced.
Building an app-store-like experience that lets users install other apps from your site is harder, because installation has historically been restricted to the current page.
The <install> element
The new <install> HTML element's content and presentation is controlled by the
browser. Similar to other permission elements like <geolocation>, the
browser's control over the button's label text, language, and appearance means
it can trust the user's click as a genuine signal of intent.
A user who clicks a button labeled "Install Wonderful Application" is unlikely to be surprised when an install prompt appears.
Because the browser renders the button, you get a trusted install affordance
with minimal code and no need to orchestrate the beforeinstallprompt ceremony
in JavaScript.
Install the current app
If the current page links to a manifest that has an
id
field, a single element is all you need:
<install></install>
The browser renders the button with standardized text and iconography, and when the user clicks it, the browser's normal installation flow kicks in.
Install a different app
To install a web app that's on a different origin than the current page, use the
installurl attribute to point to the other web app:
<install installurl="https://awesome-app.com/"></install>
If the page at https://awesome-app.com links to a
manifest which defines an id field, then that's all you need to do.
If no id field exists, use the manifestid attribute to provide a computed
manifest id:
<install installurl="https://awesome-app.com/"
manifestid="https://awesome-app.com/?source=pwa">
</install>
To get the computed manifest id:
- Open DevTools.
- Go to the Application tab.
- Under the Identity section, copy the Computed App ID value.
Using the <install> button to install other origin apps means you can build a
catalog page that lets users install multiple apps, each with its own
<install> button.
Provide fallback content
If the browser doesn't support the <install> element, whatever HTML you put
inside the element is displayed:
<install installurl="https://awesome-app.com/">
<a href="https://awesome-app.com/">Launch Awesome App</a>
</install>
Detect support
If the fallback content isn't enough for your use case and you prefer to
implement a different user experience on browsers that don't support the
<install> element, use JavaScript to detect support:
if ('HTMLInstallElement' in window) {
// The <install> element is supported.
}
Handle events
The <install> element fires events you can listen to for success, dismissal,
and validation errors:
const button = document.querySelector('install');
button.addEventListener('promptaction', () => {
console.log('Installation succeeded');
});
button.addEventListener('promptdismiss', () => {
console.log('User dismissed the install prompt');
});
button.addEventListener('validationstatuschanged', (e) => {
if (e.target.invalidReason === 'install_data_invalid') {
console.error('Invalid install data:', e.target.invalidReason);
}
});
Try it today
To try the <install> element today, you have two options:
- Test the element locally on your device only.
- Test the element in real conditions, with your users, by registering for the origin trial.
Test locally
To test the element on your own device today:
- Use Chrome or Edge version 148 or later.
- Go to
about://flags/#web-app-install-elementin a new tab. - Set Web App Install Element to Enabled.
- Restart the browser.
Test on your live site using the origin trial
The origin trial lets real users on your production site use the feature without having to enable the flag first.
- Open the
<install>element origin trial registration page. - Sign in.
- Click Register.
- Enter your site's origin, and fill the rest of the form.
- Once the form is submitted, you get a token string.
- Add the token to your site's pages by using a
<meta>tag:
<meta http-equiv="origin-trial" content="YOUR_TOKEN_HERE">
Alternatively, you can send the token as an HTTP response header instead:
Origin-Trial: YOUR_TOKEN_HERE
The origin trial is available for both Chrome and Edge in versions 148 through 153, and the same token will work in both browsers. To learn more about origin trials, see:
- Get started with origin trials, for Chrome.
- Test experimental APIs and features by using origin trials, for Edge.
See it in action
Check out the <install> Element Store
demo, a
PWA catalog that uses the <install> element to let you install several sample
apps.
Comparison to the Web Install API
The <install> element isn't the only way we're experimenting with how to
improve app installations on the web.
Previously, we experimented with the Web Install API (navigator.install()),
which is an imperative JavaScript API that also lets your site trigger
installation of same-origin or cross-origin web apps. To learn more, see The
Web Install API is ready for
testing.
The Web Install API also has its own origin trial.
Here's how the two approaches compare:
element |
navigator.install() API |
|
|---|---|---|
| Approach | Declarative HTML | Imperative JavaScript |
| Code required | A single HTML element | JavaScript to call navigator.install() and handle the returned promise |
| Browser trust | High: the browser controls the button's content and appearance, similar to permission elements | Low: requires a user activation (click, tap) as a trust signal |
| Cross-origin install | Yes, with installurl |
Yes, by passing a URL to navigator.install() |
| Customization | Minimal: the browser decides how the button looks | Full: you design your own UI and call the API from any interaction |
| Fallback | Built-in: child content renders if the element is unsupported | You write your own feature detection and fallback logic |
| Best for | Drop-in install buttons with minimal code; scenarios where browser-trusted UI is desirable | Custom install flows, dynamic catalog UIs, integration into existing JavaScript-heavy interfaces |
Let us know what you think
We're actively seeking feedback on both approaches. Depending on your needs, we
could add support for the <install> element, or the navigator.install() API,
or both.
To share feedback about the <install> element, open an issue on the WICG repo
dedicated to this
proposal.
To share feedback about the navigator.install() API, add a comment to the
Developer Feedback: navigator.install versus <install>
element
issue.