SDK Configuration
Point the Grovs mobile SDKs at your self-hosted backend and wire up Universal Links / App Links.
By default the Grovs SDKs connect to the managed Grovs cloud. To use your self-hosted backend, pass your SDK host as the baseURL when you initialize the SDK.
Deploy your stack first, then create a project in the dashboard to get an API key. There is a separate key per environment (test vs production).
The base URL is your SDK host
Pass baseURL = https://<SDK_HOST> — e.g. https://sdk.acme.com. This is the sdk. host under your app domain (SERVER_HOST), not the bare domain and not your links domain.
Pass baseURL in every configure(...) call, including release/production builds. If you omit it (a common mistake in an #else / release branch), the SDK falls back to the hosted Grovs cloud (sqd.link) and your self-hosted links won't resolve. Also match useTestEnvironment (testEnvironment on the web) to the API key's environment: test key → true, production key → false. A production link opened by a test-mode app (or vice-versa) won't resolve its payload.
iOS
import Grovs
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Grovs.configure(
APIKey: "your-api-key",
useTestEnvironment: false,
baseURL: "https://sdk.example.com", // your SDK_HOST
delegate: self
)
return true
}Android
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Grovs.configure(this, "your-api-key", useTestEnvironment = false, baseURL = "https://sdk.example.com")
}
}Flutter
The Flutter plugin has no configure call in Dart. It reads the base URL from the native config files at launch, so set grovs_base_url and GrovsBaseURL in every build variant you ship, including release. If your self-hosted links use copy-to-clipboard deferred deep linking, list your link hosts under grovs_clipboard_domains / GrovsClipboardDomains as well, so the SDK recognizes them on the clipboard.
<application>
<meta-data android:name="grovs_api_key" android:value="YOUR_API_KEY" />
<meta-data android:name="grovs_use_test_environment" android:value="false" />
<meta-data android:name="grovs_base_url" android:value="https://sdk.example.com" />
<!-- Optional: comma-separated link hosts for clipboard deferred deep linking -->
<meta-data android:name="grovs_clipboard_domains" android:value="a1b2c3d4.acme.link" />
</application>The full key table is in the Flutter Quick Start.
React Native
Grovs.configure(
APIKey: "your-api-key",
useTestEnvironment: false,
baseURL: "https://sdk.example.com",
autoTrackScreenViews: false,
clipboardDomains: nil,
enabled: GrovsWrapperSwift.isSDKEnabled(),
delegate: nil // the wrapper registers itself as the delegate
)The other parameters are explained in the React Native Quick Start.
Web
import Grovs from 'grovs';
await Grovs.configure({
apiKey: 'your-api-key',
baseURL: 'https://sdk.example.com', // your SDK_HOST
onDeeplink: (payload) => {
console.log('Link payload:', payload);
},
});Server-to-server
Use the same host with header auth:
POST https://sdk.example.com/...
PROJECT-KEY: your-api-key
ENVIRONMENT: production # or "test"
Universal Links & App Links
Your deep links live on per-project subdomains of your links domain and test links domain (random subdomains like a1b2c3d4.acme.link and a1b2c3d4.test.acme.link), so your app must associate with the wildcards, not a single subdomain.
Associated Domains (iOS)
In Xcode → Signing & Capabilities → Associated Domains, add the wildcard for both domains:
applinks:*.<DOMAIN_LIVE>
applinks:*.<DOMAIN_TEST>
With the defaults, that is applinks:*.acme.com and applinks:*.test.acme.com.
App Links (Android)
Add intent filters for your project's link hosts in AndroidManifest.xml. Android verifies App Links per concrete host, so use the project's own link subdomains, one for each environment; the dashboard shows them on the project's Domain page:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="a1b2c3d4.acme.link" />
</intent-filter>The backend serves the /.well-known/apple-app-site-association and /.well-known/assetlinks.json files on each link host, including verified custom domains, so you don't host them yourself. They return 404 until the project has the platform configured (bundle ID and Team ID, or package name and fingerprint) and the platform's redirect rule is enabled in the dashboard. Fetch the URL in a browser to check; the response names the missing piece.
TLS for reliable Universal Links. Per-project link subdomains get their TLS certificate on demand on first request (≈ a few seconds). Apple's association CDN can time out during that cold-start and cache the failure for ~1 hour, so the app won't open the link. For production, pre-issue a wildcard certificate (*.<DOMAIN_LIVE>, *.<DOMAIN_TEST>) via your DNS provider's API so every subdomain has TLS instantly. For development, you can append ?mode=developer to an applinks: entry and enable Settings → Developer → Associated Domains Development to fetch the association directly from your server, bypassing Apple's CDN.
After installing the app, delete-and-reinstall when you change Associated Domains — iOS caches the association at install time.
Verifying the connection
First confirm the SDK host answers:
curl -sS https://<SDK_HOST>/up # -> 200Then enable debug logging in the app and confirm the SDK authenticates against your host:
Grovs.setDebug(level: .info)