Skip to content

Add Smart App Banner to share pages for post-install one-tap re-open #7

@variablefate

Description

@variablefate

Goal

Add Apple's Smart App Banner (<meta name="apple-itunes-app">) to each driver-share page so that a user who has RoadFlare installed and revisits roadflare.app/share/d/<npub> in iOS Safari sees a native "OPEN" banner that launches the app pre-filled with the driver. For users without the app, the same banner shows "VIEW" → App Store.

This is a one-<meta>-tag quick-win, complementary to the App Clip work that bridges the first-install gap. It does NOT replace App Clip.

Why this is its own issue

<meta name="apple-itunes-app"> only carries app-argument to an already-installed app. The argument is stripped by iOS during install. So this issue covers exactly one case: a returning user who already has RoadFlare and re-opens a share link in Safari. Common scenario — driver texts the share URL to a rider, rider taps once before installing (App Clip handles that — see variablefate/roadflare-ios#75), then later reopens the same link to add another driver.

Implementation

Single change to 404.html (the SPA router for /share/d/<npub> and /share/r/<npub>).

Inside renderSharePage(type, npub), after the npub is parsed and BEFORE any heavy rendering, inject the meta tag:

// Smart App Banner — drivers only; rider scheme has no handler yet.
if (isDriver) {
    const meta = document.createElement('meta');
    meta.name = 'apple-itunes-app';
    const realName = profile.display_name || profile.name || '';
    const nameParam = realName ? '?name=' + encodeURIComponent(realName) : '';
    meta.content = `app-id=6761305625, app-argument=roadflared:${npub}${nameParam}`;
    document.head.appendChild(meta);
}

(Skip on rider shares for now — roadflarer: has no iOS handler today; setting the meta there would surface an "OPEN" button that does nothing useful until a future driver app ships and registers the scheme.)

How this interacts with the rest of the deep-link surface

Three layers of share-link → app dispatch are converging:

Layer Status Pre-install? Post-install?
Smart App Banner (this issue) proposed falls back to App Store via app-id "OPEN" button passes roadflared:<npub> to running app
App Clip (variablefate/roadflare-ios#75) proposed downloads ~10 MB clip, previews driver, hands off via App Group on install bypassed in favor of Universal Link
Universal Links (variablefate/roadflare-ios#63) proposed falls back to current share page https://roadflare.app/share/d/<npub> opens app directly

The three are additive — same AASA on this site can host applinks (#63) and appclips (#75) sections side by side; this issue's meta tag is independent and lives in the rendered HTML, not AASA.

Limitations (intentionally accepted)

  • Only Safari renders Smart App Banners. Chrome iOS does not — but Chrome iOS users tapping share links from Mail/Messages get routed through Safari anyway.
  • app-argument is NOT preserved through install. App Clip (variablefate/roadflare-ios#75) is the answer for first-install context bridging.
  • Some users dismiss the banner. iOS persists the dismissal per-domain. Not worth fighting.
  • Banner shows above the existing share-page UI, briefly nudging the page down. Acceptable.

Prerequisites

  • PR variablefate/roadflare-ios#66 merged + shipped to App Store. The banner's app-argument=roadflared:<npub> value relies on the iOS app's URL-scheme handler that #66 introduces. Until #66 is live in an App Store build, the banner would correctly route to the App Store install but tapping "OPEN" on an existing pre-#66 install would do nothing.
  • Site PR can be opened ahead of time and held draft until #66 ships, similar to draft PRs #4 and #5.

Out of scope

  • Rider share banner (no roadflarer: handler exists yet)
  • AASA changes (handled by #63 / #75 on the iOS-app side)
  • Tracking the user across the install gap (that's #75's job, and explicitly NOT this issue's)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions