Docs
grovs.io Start for free

Link creation

Generate smart links programmatically in your Android app.

Create smart links from your app with generateLink, using a callback or coroutines.

Using a callback

Kotlin
Grovs.generateLink(
    title = "Check out this product",
    subtitle = "Limited time offer",
    imageURL = "https://example.com/image.jpg",
    data = mapOf("productId" to "12345", "screen" to "product_detail"),
    tags = listOf("promotion", "share"),
    tracking = TrackingParams(
        utmCampaign = "spring_sale",
        utmSource = "in_app",
        utmMedium = "share_button"
    ),
    lifecycleOwner = this,
    listener = { link, error ->
        link?.let { Log.d("Grovs", "Generated: $it") }
        error?.let { Log.e("Grovs", "Error: $it") }
    }
)

The listener runs on the main thread. Pass a lifecycleOwner to drop the callback if the Activity or Fragment is destroyed first.

Using coroutines

Kotlin
lifecycleScope.launch {
    try {
        val link = Grovs.generateLink(
            title = "Check out this product",
            subtitle = "Limited time offer",
            imageURL = "https://example.com/image.jpg",
            data = mapOf("productId" to "12345"),
            tags = listOf("promotion"),
            tracking = TrackingParams(
                utmCampaign = "spring_sale",
                utmSource = "in_app",
                utmMedium = "share_button"
            )
        )
        Log.d("Grovs", "Generated: $link")
    } catch (e: GrovsException) {
        Log.e("Grovs", "Error: ${e.message}")
    }
}

The SDK must be configured and authenticated. Until then the callback reports a GrovsException and the coroutine form throws one.

Parameters

ParameterTypeDescription
titleString?Link preview title
subtitleString?Link preview subtitle
imageURLString?Link preview image URL
dataMap<String, Serializable>?Custom payload delivered on deep link open
tagsList<String>?Tags for filtering and analytics
customRedirectsCustomRedirects?Override the default redirect per platform. See Custom redirects
showPreviewIosBoolean?Show the link preview page on iOS. null uses the project default
showPreviewAndroidBoolean?Show the link preview page on Android. null uses the project default
copyToClipboardIosBoolean?Copy the link to the clipboard from the preview page on iOS, for clipboard-assisted deferred deep linking. null inherits the project setting
copyToClipboardAndroidBoolean?Same, for Android. null inherits the project setting
trackingTrackingParams?UTM campaign, source and medium
lifecycleOwnerLifecycleOwner?Callback form only. Scopes the callback to a lifecycle
listenerGrovsLinkGenerationListenerCallback form only. Receives the link or a GrovsException

copyToClipboardIos and copyToClipboardAndroid apply only when that platform shows the preview page. Passing false is an explicit override, unlike omitting the parameter.

Custom redirects

Override where a link sends users per platform:

Kotlin
val redirects = CustomRedirects(
    ios = CustomLinkRedirect(link = "https://example.com/ios-promo"),
    android = CustomLinkRedirect(link = "https://example.com/android-promo"),
    desktop = CustomLinkRedirect(link = "https://example.com/desktop-promo", openAppIfInstalled = false)
)
 
Grovs.generateLink(
    title = "Special offer",
    data = mapOf("promoId" to "summer25"),
    customRedirects = redirects,
    lifecycleOwner = this,
    listener = { link, error ->
        link?.let { Log.d("Grovs", "Generated: $it") }
    }
)

With openAppIfInstalled true (default), the app opens if installed, otherwise the redirect URL is used. With false, the redirect URL is always used.

Launch a share intent once the link is ready:

Kotlin
Grovs.generateLink(
    title = "Share this",
    data = mapOf("itemId" to "abc"),
    lifecycleOwner = this,
    listener = { link, _ ->
        link?.let {
            val sendIntent = Intent().apply {
                action = Intent.ACTION_SEND
                putExtra(Intent.EXTRA_TEXT, it)
                type = "text/plain"
            }
            startActivity(Intent.createChooser(sendIntent, "Share via"))
        }
    }
)

Next steps

Last updated 2026-10-27
Was this page helpful?