리치 설치 UI를 추가하는 방법

앱 스토어는 사용자가 앱 설치를 선택하는 데 도움이 되는 스크린샷과 텍스트 정보를 통해 앱을 설치하기 전에 개발자가 앱을 선보일 수 있는 공간을 제공합니다. 유사한 설치 UI를 통해 웹 앱 개발자가 브라우저에서 직접 사용자를 초대하여 앱을 설치할 수 있습니다. 이 향상된 UI는 Android용 Chrome 및 데스크톱 환경에서 사용할 수 있습니다.

기본 메시지

충분한 컨텍스트를 제공하지 않는 기본 환경은 아래 예를 참고하세요.

데스크톱용 브라우저 기본 설치 대화상자입니다.
데스크톱에 기본 설치 대화상자


모바일용 브라우저의 기본 설치 대화상자입니다.
모바일에서 기본 설치 대화상자

더욱 풍부한 설치 UI

일반적인 작은 기본 메시지 대신 더 풍부한 설치 UI 대화상자를 표시하려면 웹 매니페스트에 screenshotsdescription 필드를 추가합니다. 아래의 Squoosh.app 예를 확인하세요.

데스크톱 및 모바일의 풍부한 설치 UI
데스크톱과 모바일의 설치 UI가 더욱 풍부해졌습니다.

풍부한 설치 UI 대화상자는 웹 매니페스트의 descriptionscreenshots 필드의 콘텐츠로 구성됩니다.

대화상자를 트리거하려면 해당하는 폼 팩터의 스크린샷을 하나 이상 추가하면 되지만 설명도 추가하는 것이 좋습니다. 해당 입력란에 대한 자세한 내용은 아래를 확인하세요.

스크린샷

스크린샷은 새로운 설치 UI에 '더 풍부한' 부분을 제공하므로 스크린샷을 사용하는 것이 좋습니다. 매니페스트에서 screenshots 구성원을 추가합니다. 이 멤버는 하나 이상의 이미지가 필요한 배열을 사용하며 Chrome에 최대 8개의 이미지가 표시됩니다. 아래 예를 참고하세요.

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

스크린샷은 다음 기준을 따라야 합니다.

  • 너비 및 높이는 320픽셀 이상 3,840픽셀 이하여야 합니다.
  • 최대 크기는 최소 크기의 2.3배를 초과할 수 없습니다.
  • 폼 팩터 값이 동일한 모든 스크린샷은 가로세로 비율이 동일해야 합니다.
  • JPEG 및 PNG 이미지 형식만 지원됩니다.
  • 스크린샷은 8개만 표시됩니다. 더 많이 추가되면 사용자 에이전트는 해당 항목을 무시합니다.

또한 이미지가 올바르게 렌더링되도록 이미지의 크기와 유형을 포함해야 합니다. 데모 보기

form_factor는 스크린샷을 데스크톱 (wide)에서 표시해야 하는지 모바일 환경 (narrow)에서 표시해야 하는지 브라우저에 나타냅니다.

설명

description 구성원은 설치 메시지에서 애플리케이션을 설명하여 사용자가 앱을 유지하도록 초대합니다.

대화상자는 description 없이도 표시되지만 권장됩니다. 최대 한도가 있으며 7줄 (영문 기준 약 324자)부터 시작되며 긴 설명은 잘리고 생략 부호가 추가됩니다 (이 예 참조).

{
…
"description": "Compress and compare images with different codecs
right in your browser."
}
설명 추가됨
설명이 추가되었습니다.
잘린 긴 설명입니다.
긴 설명은 잘립니다.

설명은 설치 프롬프트 상단에 표시됩니다.

스크린샷을 보면 설치 대화상자에 앱의 출처도 표시됩니다. UI에 맞추기에 너무 긴 출처는 잘립니다. 이를 생략이라고도 하며 사용자를 보호하기 위한 보안 조치로 사용됩니다.

추가 자료

데모

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();
  });
}