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

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

Comando padrão

Confira o exemplo abaixo para a experiência padrão, que não oferece 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 no computador


A caixa de diálogo de instalação padrão do navegador para dispositivos móveis.
Caixa de diálogo de instalação padrão no dispositivo móvel

Interface de instalação mais avançada

Para receber a caixa de diálogo da interface de instalação mais avançada em vez do comando padrão pequeno normal, 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, basta adicionar pelo menos uma captura de tela para o fator de forma correspondente, mas também é recomendável adicionar a descrição. Confira as especificidades desses campos abaixo.

Capturas de tela

As capturas de tela realmente adicionam a parte "mais avançada" à nova interface de instalação, e recomendamos muito o uso delas. No manifesto, adicione o membro screenshots, que usa uma matriz que exige pelo menos uma imagem, e o Chrome vai mostrar 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 ser de pelo menos 320 pixels e no máximo 3.840 pixels.
  • A dimensão máxima não pode ser mais de 2,3 vezes maior que a dimensão mínima.
  • Todas as capturas de tela com o mesmo valor de fator de forma precisam ter proporções idênticas.
  • Somente os formatos de imagem JPEG e PNG são aceitos.
  • Apenas oito capturas de tela serão mostradas. Se mais forem adicionadas, o user agent simplesmente as ignorará.

Além disso, é necessário incluir o tamanho e o tipo da imagem para que ela seja renderizada corretamente.

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

Descrição

O membro description descreve o aplicativo no comando de instalação para convidar o usuário a manter o app.

A caixa de diálogo será exibida mesmo sem uma description, mas é recomendável. Há um limite máximo que é ativado após sete linhas de texto (aproximadamente 324 caracteres), e as descrições mais longas são truncadas e uma reticência é anexada.

{

"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 do comando de instalação.

Você pode ter notado nas capturas de tela que as caixas de diálogo de instalação também listam a origem do app. As origens que são muito longas para caber na interface são truncadas. Isso também é conhecido como elisão 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();
  });
}