---
source_url: https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/links
title: Links
updated_at: 2026-06-17T11:37:16.561Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Links

Encode URLs (`www`, `http`, `https`) as clickable links or create hyperlinks with custom text.

:::tip Generic referencing
Channel references, user mentions, and links share the same `MessageElement` structure with different `MentionTarget` values.
:::

## Add links

`addMention()` adds a link to a [draft message](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/drafts).

### Method signature

Call `addMention()` with the `target` of `MentionTarget.url`. See [addMention()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/drafts#add-message-element) for details.

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

Create the `Hello Alex! I have sent you this link on the #offtopic channel.` message where `link` is a URL.

```swift
// Assumes a "ChannelImpl" reference named "channel"
// Create a message draft.
let messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered: channel.type != .public)
// Update the text of the message draft
messageDraft.update(text: "Hello Alex! I have sent you this link on the #offtopic channel.")
// Add a URL mention to the word "link"
messageDraft.addMention(offset: 33, length: 4, target: MentionTarget.url(url: "https://example.com"))

// Additional logic can be implemented as needed
// For example, sending the draft or adding listeners
```

## Remove links

`removeMention()` removes a link from a [draft message](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/drafts).

### Method signature

Call `removeMention()` at the exact offset where the link starts. See [removeMention()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/drafts#remove-message-element) for details.

:::warning Offset value
If you don't provide the position of the first character of the message element to remove, it isn't removed.
:::

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

Remove the link from the `Hello Alex! I have sent you this link on the #offtopic channel.` message where `link` is a URL.

```swift
// Assumes a "MessageDraftImpl" reference named "messageDraft"

// Assume the message reads: "Hello Alex! I have sent you this link on the #offtopic channel."
// Remove the link mention
messageDraft.removeMention(offset: 33)
```

## Get link suggestions

The message elements listener returns link suggestions matching a 3-letter string in the [draft message](https://www.pubnub.com/docs/chat/swift-chat-sdk/learn/chat-entities/message-draft).

##### Single listener

The message elements listener returns suggestions for channel references, user mentions, and links.

This listener monitors changes in a message draft through the `onChange` method, which takes `messageElements` and `suggestedMentions` as parameters.

* `MessageElements` represent the draft's current state and can include plain text or links, such as user mentions, channel references, or URLs. These elements are organized to reflect their order in the draft.
* `SuggestedMentions` operates as a `Future` object, asynchronously providing potential mentions when available.

### Method signature

Add a message elements listener to receive link suggestions. See [addChangeListener()](https://www.pubnub.com/docs/chat/swift-chat-sdk/build/features/messages/drafts#add-message-draft-change-listener) for details.

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

```swift
// Define the listener conforming to MessageDraftChangeListener protocol.
// You can also use our ClosureMessageDraftChangeListener class to reduce the need for your custom types to implement the MessageDraftChangeListener protocol
class LinkSuggestionListener: MessageDraftChangeListener {
  func onChange(messageElements: [MessageElement], suggestedMentions: any FutureObject<[SuggestedMention]>) {
    // Update UI with message elements
    // This function is your own function for updating UI
    updateUI(with: messageElements)
    // Asynchronously process suggested URL mentions
    suggestedMentions.async { result in
      switch result {
      case .success(let mentions):
        // This is your own function for updating URL suggestions
        updateLinkSuggestions(with: mentions)
      case .failure(let error):
        print("Error retrieving URL suggestions: \(error)")
      }
    }
  }
}

// Create a message draft.
// Assumes a "ChannelImpl" reference named "channel"
let messageDraft = channel.createMessageDraft(isTypingIndicatorTriggered: channel.type != .public)
// Instantiate the listener
let listener = LinkSuggestionListener()
// Add the listener to the message draft
messageDraft.addChangeListener(listener)

func updateUI(with: [MessageElement]) {}
func updateLinkSuggestions(with: [SuggestedMention]) {}
```

## Get text links

`getMessageElements()` returns all text links in a message.

### Method signature

This method has the following signature:

```swift
message.getMessageElements()
```

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

Get all text links included in the message with the `16200000000000000` timetoken.

```swift
// Assumes a "MessageImpl" reference named "message"
// Retrieve the message elements
let messageElements = message.getMessageElements()

// Filter the message elements to get only text links
let textLinks = messageElements.compactMap {
  switch $0 {
  case let .link(text, target):
    if case let .url(url) = target {
      return URL(string: url)
    } else {
      return nil
    }
  default:
    return nil
  }
}

// Print the text links found, if any
if !textLinks.isEmpty {
  print("The message contains the following text links:")
  textLinks.forEach { link in
    print(link.absoluteString)
  }
} else {
  print("The message does not contain any text links.")
}
```

## Get text links (deprecated)

`textLinks` returns all text links in a message.

### Method signature

This method has the following signature:

```swift
message.textLinks
```

### Sample code

:::tip Sample code
The code samples in Swift Chat SDK focus on asynchronous code execution.
You can also write synchronous code as the parameters are shared between the async and sync methods but we don't provide usage examples of such.
:::

Get all text links included in the message with the `16200000000000000` timetoken.

```swift
// Assumes a "ChatImpl" reference named "chat"
Task {
  if let channel = try await chat.getChannel(channelId: "your-channel") {
    if let message = try await channel.getMessage(timetoken: 16200000000000000) {
      if let textLinks = message.textLinks, !textLinks.isEmpty {
        for textLink in textLinks {
          debugPrint("Link: \(textLink.link), Start Index: \(textLink.startIndex), End Index: \(textLink.endIndex)")
        }
      } else {
        debugPrint("The message does not contain any text links.")
      }
    } else {
      debugPrint("Message does not exist")
    }
  } else {
    debugPrint("Channel not found")
  }
}
```