# Link creation

> Generate smart links programmatically in your React Native app, and look up a link by path.

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

Create smart links from your app with `generateLink`, and read a link back with `linkDetails`.

## Generating a link

Pass one options object. Every field is optional:

```typescript
import Grovs from 'react-native-grovs-wrapper';

try {
    const link = await Grovs.generateLink({
        title: 'Check out this product',
        subtitle: 'Limited time offer',
        imageURL: 'https://example.com/image.jpg',
        data: { productId: '12345', screen: 'product_detail' },
        tags: ['promotion', 'share'],
        tracking: {
            utm_campaign: 'spring_sale',
            utm_source: 'in_app',
            utm_medium: 'share_button',
        },
    });
    console.log('Generated:', link);
} catch (error) {
    console.error('Error:', error);
}
```

The native SDK must be configured and authenticated. Until then the promise rejects with an `Error` whose message starts `Failed to generate link:`. While disabled with `setSDK(false)`, it rejects with `code` `'SDK_DISABLED'`. See [Privacy & Consent](https://docs.grovs.io/docs/sdk/react-native/privacy#while-the-sdk-is-disabled).

## Parameters

| Parameter                | Type                                           | Description                                                                                                                                                                                                                                                      |
| ------------------------ | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title`                  | `string?`                                      | Link preview title                                                                                                                                                                                                                                               |
| `subtitle`               | `string?`                                      | Link preview subtitle                                                                                                                                                                                                                                            |
| `imageURL`               | `string?`                                      | Link preview image URL                                                                                                                                                                                                                                           |
| `data`                   | `{ [key: string]: Any }?`                      | Custom payload delivered on deep link open. Strings, numbers, booleans and flat arrays of those                                                                                                                                                                  |
| `tags`                   | `Any[]?`                                       | Tags for filtering and analytics. Pass strings                                                                                                                                                                                                                   |
| `customRedirects`        | `CustomRedirects?`                             | Override the default redirect per platform. See [Custom redirects](#custom-redirects)                                                                                                                                                                            |
| `showPreviewIos`         | `boolean?`                                     | Show the link preview page on iOS. Leave `undefined` to use the project default                                                                                                                                                                                  |
| `showPreviewAndroid`     | `boolean?`                                     | Show the link preview page on Android. Leave `undefined` to use the project default                                                                                                                                                                              |
| `tracking`               | `{ utm_campaign?, utm_source?, utm_medium? }?` | UTM campaign, source and medium                                                                                                                                                                                                                                  |
| `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/react-native/deep-linking#clipboard-assisted-deferred-deep-linking). Leave `undefined` to inherit the project setting |
| `copyToClipboardAndroid` | `boolean?`                                     | Same, for Android. Leave `undefined` to inherit the project setting                                                                                                                                                                                              |

`copyToClipboardIos` and `copyToClipboardAndroid` apply only when that platform shows the preview page. Passing `false` is an explicit override, unlike leaving the field out. Flow and limits: [Copy to Clipboard](https://docs.grovs.io/docs/links/copy-to-clipboard).

```typescript
const link = await Grovs.generateLink({
    title: 'Invite a friend',
    data: { referrer: 'user-123' },
    copyToClipboardIos: true,
    copyToClipboardAndroid: true,
});
```

### Positional form

The 1.x positional signature still works, with the two copy flags appended. Prefer the options object in new code.

```typescript
Grovs.generateLink(
    title, subtitle, imageURL, data, tags, customRedirects,
    showPreviewIos, showPreviewAndroid, tracking,
    copyToClipboardIos, copyToClipboardAndroid
)
```

## Custom redirects

Override where a link sends users per platform:

```typescript
const link = await Grovs.generateLink({
    title: 'Special offer',
    data: { promoId: 'summer25' },
    customRedirects: {
        ios: { link: 'https://example.com/ios-promo', open_if_app_installed: true },
        android: { link: 'https://example.com/android-promo', open_if_app_installed: true },
        desktop: { link: 'https://example.com/desktop-promo', open_if_app_installed: false },
    },
});
```

With `open_if_app_installed` `true`, the app opens if installed, otherwise the redirect URL is used. With `false`, the redirect URL is always used. The `CustomRedirects` type requires all three platforms.

From 3.1.0, Android forwards each platform's own flag. In wrapper 3.0.x, Android sent the `ios` flag for `desktop` (new architecture) or always `true` (legacy bridge).

## Sharing the link

Pass the link to the system share sheet:

```typescript
import { Share } from 'react-native';
import Grovs from 'react-native-grovs-wrapper';

const link = await Grovs.generateLink({ title: 'Share this', data: { itemId: 'abc' } });
await Share.share({ message: link });
```

## Inspecting a link

`linkDetails` (3.1.0) fetches a link generated in the current environment by its path: the part after the domain, without the leading `/` and without a query string.

```typescript
try {
    const details = await Grovs.linkDetails('abc123');
    console.log(details.title, details.data, details.tags);
} catch (error) {
    // the link doesn't exist, the request failed, or the SDK is disabled (code 'SDK_DISABLED')
}
```

The result is a [`LinkDetails`](https://docs.grovs.io/docs/sdk/react-native/api-reference#linkdetails-1) with the backend's snake_case fields, such as `path`, `title`, `subtitle`, `image`, `data`, `tags`, `access_path`, `active`, the tracking fields and the custom redirects. An empty path rejects before the request.

## Next steps

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