ENGLISH·COURSE API
    Preparing search index...
    • Client hook: which install route this browser offers, and what it needs to take it.

      Returns InstallPath

      The route to offer, carrying the browser's offer where there is one

      Composed from the two signals rather than merged into one, because they rest on different evidence. useSafariInstallSurface reads a user agent and a touch-point count, which is all Apple gives anyone. useInstallPrompt waits for an event the browser actually fired. Folding them into a single predicate would hide that one of them is a guess and the other is a fact.

      The three Safari surfaces are three routes rather than one, because the taps differ and so do the surfaces they happen on: an iPad guide shown to a Mac would name controls the learner does not have.

      The prompt wins where both hold. Performing the install beats describing it, and although they cannot overlap today — Safari fires no such event — writing the precedence down means a WebKit that starts firing one does the better thing without another change here.

      Both sources report nothing until hydration commits, so this does too.

      const path = useInstallPath();

      if (path.kind === "none") return null;
      return <InstallAppButton path={path} />;
      • useInstallPrompt
      • useSafariInstallSurface