Docs

Deferred Deep Linking

What happens when a link is clicked before the app is installed, and why the payload sometimes doesn't arrive on first launch.

Deferred deep linking covers the case where a user clicks a Grovs link but doesn't have your app installed yet. The link redirects them to the store (or your configured fallback), and after they install and open the app, Grovs matches the earlier click to the new install and delivers the link's payload — so the user still lands on the screen the link pointed to. Grovs handles this automatically; there is no separate API for it.

How the payload arrives

The deferred payload is delivered through the same callback as a regular deep link, on the first launch after install:

Your routing code doesn't need to distinguish deferred from direct opens — handle the payload the same way in both cases.

Common pitfalls

Installing from Xcode or Android Studio instead of after the click

Cause: The number one testing mistake. If you install the build first and click the link afterwards, that's a direct deep link, not a deferred one — you never exercised the deferred path at all.

Fix: Test deferred deep linking in this exact order:

  1. Uninstall the app from the test device.
  2. Click the Grovs link on that device — you'll be redirected to the store page or fallback URL.
  3. Install and launch the app on the same device. Installing your development build from Xcode or Android Studio at this step is fine for testing — the point is that the click happened before the install.
  4. The payload should arrive in your delegate/listener shortly after the SDK initializes on first launch.

Listener registered too late

Cause: The deferred payload is delivered early in the first launch. If your delegate or listener is set up after that (for example, only on a screen deeper in the app), the callback can fire before anyone is listening.

Fix: Register the handler at app entry — Grovs.delegate in viewDidLoad/app startup on iOS, the listener in your launcher activity on Android, and the stream/callback in your root component on Flutter and React Native. On iOS you can also recover missed payloads with Grovs.lastReceivedPayload or Grovs.allReceivedPayloadsSinceStartup — see Retrieving past payloads.

Click and install happened in different environments

Cause: You clicked a link from the test environment but launched a build configured for production (or vice versa). The click and the install are recorded in different environments, so no match is made.

Fix: Make sure the link's environment matches the build's useTestEnvironment setting. See Test vs production environment mismatch.

Click and install on different devices

Cause: Deferred matching connects a click to an install on the same device. Clicking the link on your laptop and installing on your phone won't produce a deferred payload.

Fix: Perform the whole flow — click, store redirect, install, first launch — on the same device.

If direct deep links (app already installed) don't work either, fix that first — see Deep link doesn't open the app. Deferred delivery uses the same SDK setup.

Edit this page on GitHubLast updated 2026-07-29