install-prompt-uxlisted
Install: claude install-skill voidcorp-core/void-harness
# install-prompt-ux
Use when adding "Install app" UX to a PWA, or when figuring out why the default browser prompt doesn't appear / appears at the wrong time. Default browser behavior is broken for most apps — too early, too generic, no recovery.
This skill is the void-harness pattern: capture the event, defer it, surface a custom button at a meaningful moment.
## The browser default is bad
Without custom code, Chrome (etc.) decides when to show a small browser-styled "Add to Home Screen" toast. The decision is opaque (engagement heuristic), the UI is generic, and once dismissed it doesn't reappear soon. Users either miss it or click "Cancel" reflexively.
Solution: hijack the prompt, defer it, show your own button.
## The `beforeinstallprompt` flow
```tsx
// apps/web/src/components/InstallPrompt.tsx
'use client';
import { useEffect, useState } from 'react';
interface BIPEvent extends Event {
prompt: () => Promise<void>;
userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>;
}
export function InstallPrompt() {
const [deferred, setDeferred] = useState<BIPEvent | null>(null);
const [isInstalled, setIsInstalled] = useState(false);
useEffect(() => {
// 1. Capture the event when the browser fires it
const onBIP = (e: Event) => {
e.preventDefault(); // don't show browser default
setDeferred(e as BIPEvent);
};
window.addEventListener('beforeinstallprompt', onBIP);
// 2. Detect already-installed (PWA op