Install web apps with the new HTML install element

Patrick Brosset
Patrick Brosset

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.

image

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:

  1. Open DevTools.
  2. Go to the Application tab.
  3. 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:

  1. Use Chrome or Edge version 148 or later.
  2. Go to about://flags/#web-app-install-element in a new tab.
  3. Set Web App Install Element to Enabled.
  4. 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.

  1. Open the <install> element origin trial registration page.
  2. Sign in.
  3. Click Register.
  4. Enter your site's origin, and fill the rest of the form.
  5. Once the form is submitted, you get a token string.
  6. 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:

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.

Resources