Deep linking
Handle incoming deep links and SDK errors in your Unity game with the Grovs SDK.
Subscribe to Grovs.DeeplinkReceived for link payloads and Grovs.ErrorOccurred for SDK failures. Both run on the Unity main thread.
Receiving deep link events
using GrovsSDK;
using UnityEngine;
public class LinkRouter : MonoBehaviour
{
void OnEnable() => Grovs.DeeplinkReceived += OnDeeplink;
void OnDisable() => Grovs.DeeplinkReceived -= OnDeeplink;
void OnDeeplink(GrovsDeeplink deeplink)
{
// Data is never null. Whole numbers arrive as long on both platforms.
if (deeplink.Data.TryGetValue("level", out var level))
LoadLevel((long)level);
Debug.Log("Link: " + deeplink.Link + ", from push: " + deeplink.FromPush);
if (deeplink.Tracking != null) Debug.Log("Campaign: " + deeplink.Tracking.Campaign);
}
void LoadLevel(long level) { /* your scene loading */ }
}The event fires for universal links and App Links, the URI scheme, deferred deep links after an install, links from Grovs push notifications, and links passed to HandleUrl.
GrovsDeeplink fields:
| Field | Type | Description |
|---|---|---|
Link | string | The opened link. Can be null. |
Data | IReadOnlyDictionary<string, object> | The link's custom payload. Never null, empty when there's none. |
Tracking | GrovsTracking | Campaign, Source and Medium. Can be null. |
FromPush | bool | true when the link came from a Grovs push notification. |
RawJson | string | The message as the native bridge sent it. |
Payload values are JSON types: string, bool, long for whole numbers, double for other numbers, null, lists and Dictionary<string, object>.
Links before the first subscriber
The native SDK starts before Unity, so a link can arrive before your scripts run. Links that arrive with no subscriber are kept, up to 20, and delivered in order to the first subscriber. Later subscribers don't get them. Subscribe early, for example in your first scene.
Grovs.LastDeeplink holds the most recent link, or null.
Links inside the game
To open a Grovs link tapped in your own UI, a chat message say:
bool handled = Grovs.HandleUrl("https://x.sqd.link/abc");- The URL must be absolute with a scheme and a host. Anything else throws
ArgumentException, andnullthrowsArgumentNullException. - Returns
falsewhile Grovs is disabled. - The result arrives in
DeeplinkReceivedlike any other link.
Handling SDK errors
Grovs.ErrorOccurred += error => Debug.LogWarning("Grovs: " + error.Code + " " + error.Message);ErrorOccurred carries errors that have no other place to be reported. Failed Tasks and callbacks carry their own error.
| Platform | What ErrorOccurred reports |
|---|---|
| iOS | Every asynchronous native SDK error: authentication, network, event dispatch, link generation and in-app display failures |
| Android | In-app message failures and bridge errors only |
Codes are listed under GrovsErrorCode. Errors are informational: the native SDK retries on its own.
Clipboard-assisted deferred deep linking
When a copy-to-clipboard link opens in a browser, the preview page copies it before sending the player to the store. On the first launch after install, the SDK reads it and attributes the install deterministically. The deferred link arrives in DeeplinkReceived, like a fingerprint match.
No code is needed. If your links use a custom domain, add it to Clipboard domains in Project Settings. Grovs-owned hosts are always accepted.
| Platform | Behavior |
|---|---|
| iOS | The system paste prompt may show on first launch. Denying it leaves the install unattributed. |
| Android | Reading the clipboard needs window focus. It works because Grovs starts before the activity. |
Turn it on per link with CopyToClipboardIos / CopyToClipboardAndroid, or set the project default in the dashboard. Flow and limits: Copy to Clipboard. How the check runs on iOS: iOS deep linking.
Getting link details
Read a link's details by its path:
try
{
IReadOnlyDictionary<string, object> details = await Grovs.GetLinkDetailsAsync("/abc");
foreach (var pair in details) Debug.Log(pair.Key + ": " + pair.Value);
}
catch (GrovsException e)
{
Debug.LogWarning("Details failed: " + e.Error);
}Or with a callback:
Grovs.GetLinkDetails("/abc", (details, error) =>
{
if (error != null) Debug.LogWarning(error);
else Debug.Log(details.Count + " fields");
});A null path throws ArgumentNullException. The dictionary holds the fields the backend returns for the link.
Testing links in the Editor
- Open Grovs → Simulate Deep Link.
- Enter Play Mode.
- Type a link and a JSON object for the data, for example
{"level": 3}. - Press Send.
DeeplinkReceived fires exactly as it would for a real link, with Tracking set to null. Use it to test routing code without a device. Everything else in the Editor goes to a stub that does nothing.
See also
- Link creation: generate links with a payload
- Push notifications: links from push taps
- Deep link not opening the app
- Deferred deep linking issues