import { useEffect, useState } from 'react' import { Share, ExternalLink, X } from 'lucide-react' function isIos() { return /iPad|iPhone|iPod/.test(navigator.userAgent) || // iPadOS 13+ reports as 'MacIntel' but has touch support, unlike a real Mac (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1) } function isStandalone() { return window.matchMedia('(display-mode: standalone)').matches || (window.navigator as unknown as { standalone?: boolean }).standalone === true } // Safari's UA also matches "Safari", so this checks for the other iOS // browsers/in-app webviews that spoof it — none of them can add to the // home screen; only Safari itself can. function isNonSafariIosBrowser() { return /CriOS|FxiOS|EdgiOS|OPiOS|mercury|GSA|DuckDuckGo|Instagram|FBAN|FBAV|Line\//.test(navigator.userAgent) } /** * iOS has no `beforeinstallprompt` API — Safari never fires it, so the * portal's Install button (?install=1) does nothing there. This shows the * manual steps instead: Share -> Add to Home Screen in Safari, or a prompt * to switch to Safari first if the page was opened in another browser/app. */ export default function IosInstallHint() { const [mode, setMode] = useState<'safari' | 'other' | null>(null) useEffect(() => { if (!isIos() || isStandalone()) return if (!new URLSearchParams(window.location.search).has('install')) return setMode(isNonSafariIosBrowser() ? 'other' : 'safari') }, []) if (!mode) return null return (
{mode === 'safari' ? : }
{mode === 'safari' ? (

To install this app, tap the Share icon in Safari's toolbar, then choose Add to Home Screen.

) : (

iOS only allows installing apps from Safari. Open this page in Safari, then tap Share → Add to Home Screen.

)}
) }