Skip to content

Instantly share code, notes, and snippets.

@AndreGtz
Forked from rikukissa/POST.md
Created June 15, 2019 02:04
Show Gist options
  • Select an option

  • Save AndreGtz/2fa0f160b6d184e73fef175f74e398dc to your computer and use it in GitHub Desktop.

Select an option

Save AndreGtz/2fa0f160b6d184e73fef175f74e398dc to your computer and use it in GitHub Desktop.
React Hook prompting the user to "Add to homescreen" 🏠 #PWA #React

React Hook for showing custom "Add to homescreen" prompt

Demo:
Twitter

Simple React Hook for showing the user a custom "Add to homescreen" prompt.

const [prompt, promptToInstall] = useAddToHomescreenPrompt();

Listens for beforeinstallprompt event, which notifies you when the browser would have shown the default dialog, intercepts it and lets you take over and show the prompt when ever you please.

Browser support and requirements

Add to Home Screen

Browser support is still quite lacking. At the time of writing, only Chrome (Desktop + Android) is supported.

Implementation

import * as React from "react";

interface IBeforeInstallPromptEvent extends Event {
  readonly platforms: string[];
  readonly userChoice: Promise<{
    outcome: "accepted" | "dismissed";
    platform: string;
  }>;
  prompt(): Promise<void>;
}

export function useAddToHomescreenPrompt(): [
  IBeforeInstallPromptEvent | null,
  () => void
] {
  const [prompt, setState] = React.useState<IBeforeInstallPromptEvent | null>(
    null
  );

  const promptToInstall = () => {
    if (prompt) {
      return prompt.prompt();
    }
    return Promise.reject(
      new Error(
        'Tried installing before browser sent "beforeinstallprompt" event'
      )
    );
  };

  React.useEffect(() => {
    const ready = (e: IBeforeInstallPromptEvent) => {
      e.preventDefault();
      setState(e);
    };

    window.addEventListener("beforeinstallprompt", ready as any);

    return () => {
      window.removeEventListener("beforeinstallprompt", ready as any);
    };
  }, []);

  return [prompt, promptToInstall];
}

Example component

import * as React from "react";
import { useAddToHomescreenPrompt } from "./useAddToHomescreenPrompt";

export function ExampleComponent() {
  const [prompt, promptToInstall] = useAddToHomescreenPrompt();
  const [isVisible, setVisibleState] = React.useState(false);

  const hide = () => setVisibleState(false);

  React.useEffect(
    () => {
      if (prompt) {
        setVisibleState(true);
      }
    },
    [prompt]
  );

  if (!isVisible) {
    return <div />;
  }

  return (
    <div onClick={hide}>
      <button onClick={hide}>Close</button>
      Hello! Wanna add to homescreen?
      <button onClick={promptToInstall}>Add to homescreen</button>
    </div>
  );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment