Instantly share code, notes, and snippets.

Embed
What would you like to do?
React Hook prompting the user to "Add to homescreen" 🏠 #PWA #React

React Hook for showing custom "Add to homescreen" prompt

(For >=React v16.7.0-alpha)

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

const [prompt, promptToInstall] = useAddToHomescreenPrompt();

Listens for "beforeinstallprompt" event (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.

Only works after certain criteria is fulfilled:

https://developers.google.com/web/fundamentals/app-install-banners/

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

Demo

https://twitter.com/rikurouvila/status/1067720501634654208

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];
}
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