Como adicionar uma IU de instalação mais avançada

As app stores oferecem um espaço para os desenvolvedores mostrarem os apps antes da instalação, com capturas de tela e informações de texto que ajudam o usuário a decidir se quer instalar o app. Uma interface de instalação mais avançada oferece um espaço semelhante para que os desenvolvedores de apps da Web convidem os usuários a instalar o app diretamente do navegador. Essa interface aprimorada está disponível no Google Chrome para ambientes de computador e Android.

Comando padrão

Confira o exemplo abaixo da experiência padrão, que não tem contexto suficiente.

A caixa de diálogo de instalação padrão do navegador para computador.
Caixa de diálogo de instalação padrão em computadores


Caixa de diálogo de instalação padrão do navegador para dispositivos móveis.
Caixa de diálogo de instalação padrão em dispositivos móveis

interface de instalação mais avançada

Para exibir a caixa de diálogo da interface de instalação mais avançada em vez da solicitação padrão pequena, adicione os campos screenshots e description ao manifesto da Web. Confira o exemplo do Squoosh.app abaixo:

Interface de instalação mais avançada em computadores e dispositivos móveis
Interface de instalação mais avançada em computadores e dispositivos móveis.

A caixa de diálogo da interface de instalação mais avançada é composta pelo conteúdo dos campos description e screenshots no manifesto da Web.

Para acionar a caixa de diálogo, você só precisa adicionar pelo menos uma captura de tela para o formato correspondente, mas também é recomendável incluir a descrição. Confira as especificidades desses campos abaixo.

Capturas de tela

As capturas de tela adicionam uma experiência para a nova interface de instalação, e é altamente recomendável usá-lo. No manifesto, você adiciona o membro screenshots, que usa uma matriz que requer pelo menos uma imagem e o Chrome vai exibir até oito. Veja um exemplo abaixo.

 "screenshots": [
    {
     "src": "source/image1.png",
      "sizes": "640x320",
      "type": "image/png",
      "form_factor": "wide",
      "label": "Wonder Widgets"
    }
]

As capturas de tela precisam seguir estes critérios:

  • A largura e a altura precisam ter pelo menos 320 px e no máximo 3.840 px.
  • A dimensão máxima não pode ser 2,3 vezes maior que a dimensão mínima.
  • Todas as capturas de tela com o mesmo formato precisam ter proporções idênticas.
  • Somente os formatos de imagem JPEG e PNG são compatíveis.
  • Apenas oito capturas de tela serão mostradas. Se mais forem adicionados, o user agent simplesmente os ignorará.

Além disso, você precisa incluir o tamanho e o tipo da imagem para que ela seja renderizada corretamente. Confira esta demonstração.

O form_factor indica ao navegador se a captura de tela deve aparecer em ambientes de computador (wide) ou de dispositivos móveis (narrow).

Descrição

O participante description descreve o app na solicitação de instalação para convidar o usuário a manter o app.

A caixa de diálogo seria mostrada mesmo sem um description, mas isso é recomendado. Há um máximo que pode ser iniciado após sete linhas de texto (cerca de 324 caracteres), e descrições mais longas são truncadas com reticências anexadas (como neste exemplo).

{
…
"description": "Compress and compare images with different codecs
right in your browser."
}
Descrição adicionada
Descrição adicionada.
Uma descrição mais longa que foi truncada.
Descrições mais longas são truncadas.

A descrição aparece na parte de cima da solicitação de instalação.

Você pode ter notado pelas capturas de tela que as caixas de diálogo de instalação também listam a origem do aplicativo. Origens que são muito longas para caber na interface são truncadas. Isso também é conhecido como eliding e é usado como uma medida de segurança para proteger os usuários.

Leitura adicional

Demonstração

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="color-scheme" content="dark light" />
    <link rel="manifest" href="manifest.json" />
    <title>How to add Richer Install UI to your web app</title>
    <!-- TODO: Devsite - Removed inline handlers -->
    <!-- <script>
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
          navigator.serviceWorker.register('sw.js');
        });
      }
    </script>
    <script type="module" src="script.js"></script> -->
  </head>
  <body>
    <h1>How to add Richer Install UI to your web app</h1>
    <ol>
      <li>
        Install the app by clicking the button below. After the installation,
        the button is disabled.
        <p>
          <button disabled type="button">Install</button>
        </p>
      </li>
      <li>
        When you click on install a dialog similar to the ones from app stores
        will be displayed.
      </li>
      <li>
        The dialog includes the `description` and `screenshots` set in the app
        manifest.
      </li>
      <li>
        Screenshots should be different depending if the app is being installed
        on a mobile or desktop device, according to the `form_factor` value set
        for the screenshots on the manifest
      </li>
    </ol>
  </body>
</html>

JS


        // The install button.
const installButton = document.querySelector('button');

// Only relevant for browsers that support installation.
if ('BeforeInstallPromptEvent' in window) {
  // Variable to stash the `BeforeInstallPromptEvent`.
  let installEvent = null;

  // Function that will be run when the app is installed.
  const onInstall = () => {
    // Disable the install button.
    installButton.disabled = true;
    // No longer needed.
    installEvent = null;
  };

  window.addEventListener('beforeinstallprompt', (event) => {
    // Do not show the install prompt quite yet.
    event.preventDefault();
    // Stash the `BeforeInstallPromptEvent` for later.
    installEvent = event;
    // Enable the install button.
    installButton.disabled = false;
  });

  installButton.addEventListener('click', async () => {
    // If there is no stashed `BeforeInstallPromptEvent`, return.
    if (!installEvent) {
      return;
    }
    // Use the stashed `BeforeInstallPromptEvent` to prompt the user.
    installEvent.prompt();
    const result = await installEvent.userChoice;
    // If the user installs the app, run `onInstall()`.
    if (result.outcome === 'accepted') {
      onInstall();
    }
  });

  // The user can decide to ignore the install button
  // and just use the browser prompt directly. In this case
  // likewise run `onInstall()`.
  window.addEventListener('appinstalled', () => {
    onInstall();
  });
}