# Link creation

> Generate smart links programmatically in your Android app.

Source: https://docs.grovs.io/docs/sdk/android/link-creation

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

## Generating a link

### 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

| Parameter                | Type                          | Description                                                                                                                                                                                                                                    |
| ------------------------ | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title`                  | `String?`                     | Link preview title                                                                                                                                                                                                                             |
| `subtitle`               | `String?`                     | Link preview subtitle                                                                                                                                                                                                                          |
| `imageURL`               | `String?`                     | Link preview image URL                                                                                                                                                                                                                         |
| `data`                   | `Map<String, Serializable>?`  | Custom payload delivered on deep link open                                                                                                                                                                                                     |
| `tags`                   | `List<String>?`               | Tags for filtering and analytics                                                                                                                                                                                                               |
| `customRedirects`        | `CustomRedirects?`            | Override the default redirect per platform. See [Custom redirects](#custom-redirects)                                                                                                                                                          |
| `showPreviewIos`         | `Boolean?`                    | Show the link preview page on iOS. `null` uses the project default                                                                                                                                                                             |
| `showPreviewAndroid`     | `Boolean?`                    | Show the link preview page on Android. `null` uses the project default                                                                                                                                                                         |
| `copyToClipboardIos`     | `Boolean?`                    | Copy the link to the clipboard from the preview page on iOS, for [clipboard-assisted deferred deep linking](https://docs.grovs.io/docs/sdk/android/deep-linking#clipboard-assisted-deferred-deep-linking). `null` inherits the project setting |
| `copyToClipboardAndroid` | `Boolean?`                    | Same, for Android. `null` inherits the project setting                                                                                                                                                                                         |
| `tracking`               | `TrackingParams?`             | UTM campaign, source and medium                                                                                                                                                                                                                |
| `lifecycleOwner`         | `LifecycleOwner?`             | Callback form only. Scopes the callback to a lifecycle                                                                                                                                                                                         |
| `listener`               | `GrovsLinkGenerationListener` | Callback 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.

## Sharing the link

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

- [Handle incoming deep links →](https://docs.grovs.io/docs/sdk/android/deep-linking)
- [Full API reference →](https://docs.grovs.io/docs/sdk/android/api-reference)
