나만의 인앱 설치 환경을 제공하는 방법

대부분의 브라우저에서는 사용자 인터페이스 내에서 직접 프로그레시브 웹 앱 (PWA) 설치를 사용 설정하고 승격할 수 있습니다. 설치 (이전 명칭: 홈 화면에 추가)를 사용하면 사용자가 휴대기기 또는 데스크톱 기기에 PWA를 설치할 수 있습니다. PWA를 설치하면 사용자의 런처에 추가되어 설치된 다른 앱과 같이 실행될 수 있습니다.

브라우저에서 제공하는 설치 환경 외에도 앱 내에서 직접 자체 맞춤 설치 흐름을 제공할 수 있습니다.

Spotify PWA에 제공된 앱 설치 버튼
Spotify PWA에 있는 '앱 설치' 버튼

설치 승격 여부를 고려할 때는 일반적으로 사용자가 PWA를 사용하는 방식을 고려하세요. 예를 들어 일주일에 PWA를 여러 번 사용하는 사용자 집합이 있는 경우, 이러한 사용자는 휴대전화 홈 화면이나 데스크톱 운영체제의 시작 메뉴에서 앱을 실행하는 데 따른 편의성을 활용할 수 있습니다. 일부 생산성 및 엔터테인먼트 애플리케이션은 설치된 standalone 또는 minimal-ui 모드의 창에서 브라우저 툴바를 삭제하여 생성된 추가 화면 공간의 이점도 누릴 수 있습니다.

기본 요건

시작하기 전에 PWA가 일반적으로 웹 앱 매니페스트가 포함된 설치 가능성 요구사항을 충족하는지 확인합니다.

설치 승격

프로그레시브 웹 앱을 설치할 수 있음을 표시하고 맞춤 인앱 설치 흐름을 제공하는 방법은 다음과 같습니다.

  1. beforeinstallprompt 이벤트를 수신합니다.
  2. 나중에 설치 흐름을 트리거할 수 있도록 beforeinstallprompt 이벤트를 저장합니다.
  3. 사용자에게 PWA를 설치할 수 있음을 알리고 인앱 설치 흐름을 시작할 수 있는 버튼 또는 기타 요소를 제공합니다.

beforeinstallprompt 이벤트 수신 대기

프로그레시브 웹 앱이 필수 설치 기준을 충족하면 브라우저에서 beforeinstallprompt 이벤트를 실행합니다. 이벤트 참조를 저장하고 사용자 인터페이스를 업데이트하여 사용자가 PWA를 설치할 수 있음을 나타냅니다.

// Initialize deferredPrompt for use later to show browser install prompt.
let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent the mini-infobar from appearing on mobile
  e.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = e;
  // Update UI notify the user they can install the PWA
  showInstallPromotion();
  // Optionally, send analytics event that PWA install promo was shown.
  console.log(`'beforeinstallprompt' event was fired.`);
});

인앱 설치 흐름

인앱 설치를 제공하려면 사용자가 클릭하거나 탭하여 앱을 설치할 수 있는 버튼 또는 기타 인터페이스 요소를 제공합니다. 요소를 클릭하거나 탭하면 저장된 beforeinstallprompt 이벤트 (deferredPrompt 변수에 저장됨)에서 prompt()를 호출합니다. PWA를 설치할 것인지 확인하는 모달 설치 대화상자가 사용자에게 표시됩니다.

buttonInstall.addEventListener('click', async () => {
  // Hide the app provided install promotion
  hideInstallPromotion();
  // Show the install prompt
  deferredPrompt.prompt();
  // Wait for the user to respond to the prompt
  const { outcome } = await deferredPrompt.userChoice;
  // Optionally, send analytics event with outcome of user choice
  console.log(`User response to the install prompt: ${outcome}`);
  // We've used the prompt and can't use it again, throw it away
  deferredPrompt = null;
});

userChoice 속성은 사용자의 선택으로 확인되는 프로미스입니다. 지연된 이벤트에서 prompt()는 한 번만 호출할 수 있습니다. 사용자가 메시지를 닫으면 beforeinstallprompt 이벤트가 다시 실행될 때까지(일반적으로 userChoice 속성이 확인된 직후) 기다려야 합니다.

PWA가 성공적으로 설치되었을 때 감지

userChoice 속성을 사용하여 사용자가 사용자 인터페이스 내에서 앱을 설치했는지 확인할 수 있습니다. 그러나 사용자가 주소 표시줄 또는 다른 브라우저 구성요소에서 PWA를 설치하는 경우에는 userChoice가 도움이 되지 않습니다. 대신 PWA를 설치하는 데 사용된 메커니즘과 관계없이 PWA가 설치될 때마다 실행되는 appinstalled 이벤트를 수신 대기해야 합니다.

window.addEventListener('appinstalled', () => {
  // Hide the app-provided install promotion
  hideInstallPromotion();
  // Clear the deferredPrompt so it can be garbage collected
  deferredPrompt = null;
  // Optionally, send analytics event to indicate successful install
  console.log('PWA was installed');
});

PWA가 실행된 방식 감지

CSS display-mode 미디어 쿼리는 PWA가 브라우저 탭에서 실행되었거나 설치된 PWA로 실행된 방식을 나타냅니다. 이렇게 하면 앱이 실행된 방식에 따라 다양한 스타일을 적용할 수 있습니다. 예를 들어 설치된 PWA로 실행될 때 항상 설치 버튼을 숨기고 뒤로 버튼을 제공하도록 구성할 수 있습니다.

PWA 실행 방식 추적

사용자가 PWA를 실행하는 방법을 추적하려면 matchMedia()를 사용하여 display-mode 미디어 쿼리를 테스트합니다. iOS의 Safari에서는 아직 이 기능을 지원하지 않으므로 브라우저가 독립형 모드로 실행 중인지 나타내는 불리언을 반환하는 navigator.standalone를 대신 확인해야 합니다.

function getPWADisplayMode() {
  const isStandalone = window.matchMedia('(display-mode: standalone)').matches;
  if (document.referrer.startsWith('android-app://')) {
    return 'twa';
  } else if (navigator.standalone || isStandalone) {
    return 'standalone';
  }
  return 'browser';
}

디스플레이 모드 변경 시 추적

사용자가 standalonebrowser tab 사이에서 변경하는지를 추적하려면 display-mode 미디어 쿼리의 변경사항을 수신 대기합니다.

window.matchMedia('(display-mode: standalone)').addEventListener('change', (evt) => {
  let displayMode = 'browser';
  if (evt.matches) {
    displayMode = 'standalone';
  }
  // Log display mode change to analytics
  console.log('DISPLAY_MODE_CHANGED', displayMode);
});

현재 디스플레이 모드에 따라 UI 업데이트

설치된 PWA로 실행할 때 PWA에 다른 배경 색상을 적용하려면 조건부 CSS를 사용합니다.

@media all and (display-mode: standalone) {
  body {
    background-color: yellow;
  }
}

앱 아이콘 및 이름 업데이트

앱 이름을 업데이트하거나 새 아이콘을 제공해야 하는 경우에는 어떻게 해야 할까요? Chrome의 웹 앱 매니페스트 업데이트 처리 방식에서 이러한 변경사항이 Chrome에 언제, 어떻게 반영되는지 확인하세요.