Skip to content

Instantly share code, notes, and snippets.

@andreguerrerosilvera
Forked from rikukissa/POST.md
Created March 25, 2019 05:04
Show Gist options
  • Select an option

  • Save andreguerrerosilvera/f880f8a2eafe089ab6a69ba7ef34396d to your computer and use it in GitHub Desktop.

Select an option

Save andreguerrerosilvera/f880f8a2eafe089ab6a69ba7ef34396d 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