TextMeshPro max link length ~120 chars

Even in the case of the URL coming from some external source or server, you would add this new URL to a List or Dictionary and use the List index or Dictionary key as the unique link ID.

Here is an example script that contains most of the glue code to handle all of this. Add this script to a normal TMP text object.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class DynamicLinkHelper : MonoBehaviour
{
    private string m_UrlFromServer = " https://discussions.unity.com/t/749791/4 ";

    private TMP_Text m_TextComponent;
    private bool m_isHoveringObject;
    private int m_SelectedLink;

    private static Dictionary<int, string> m_UrlLookup = new Dictionary<int, string>();

    private void Awake()
    {
        m_TextComponent = GetComponent<TMP_Text>();

        // Some block of code would exist here to get a URL from some sever

        // Url would then be added to our dictionary
        int linkID = AddURL(m_UrlFromServer);

        m_TextComponent.text = "Simple <style=\"link\"><link=\"" + linkID + "\">Dynamic Link</link></style> Example.";
    }

    void Update()
    {
        m_isHoveringObject = false;

        if (TMP_TextUtilities.IsIntersectingRectTransform(m_TextComponent.rectTransform, Input.mousePosition, Camera.main))
            m_isHoveringObject = true;

        // Check if mouse intersects with any links.
        int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextComponent, Input.mousePosition, Camera.main);

        // Clear previous link selection if one existed.
        if ((linkIndex == -1 && m_SelectedLink != -1) || linkIndex != m_SelectedLink)
            m_SelectedLink = -1;

        // Handle new Link selection.
        if (linkIndex != -1 && linkIndex != m_SelectedLink)
        {
            m_SelectedLink = linkIndex;

            TMP_LinkInfo linkInfo = m_TextComponent.textInfo.linkInfo[linkIndex];
            string linkIDString = linkInfo.GetLinkID();

            // The following provides an example of how to access the link properties.
            Debug.Log("Link ID: \"" + linkIDString + "\"   Link Text: \"" + linkInfo.GetLinkText() + "\"" + "\nLink URL: [" + GetLinkURL(linkIDString)); // Example of how to retrieve the Link ID and Link Text.
        }
    }


    static int AddURL(string url)
    {
        // Compute a hashcode for the given URL. This hashcode will become our unique link ID.
        int hashCode = TMP_TextUtilities.GetSimpleHashCode(url);

        if (!m_UrlLookup.ContainsKey(hashCode))
            m_UrlLookup.Add(hashCode, url);

        return hashCode;
    }

    static int GetLinkID(string url)
    {
        // Compute a hashcode for the given URL. This hashcode will become our unique link ID.
        int hashCode = TMP_TextUtilities.GetSimpleHashCode(url);

        if (m_UrlLookup.ContainsKey(hashCode))
            return hashCode;

        return -1;
    }

    static string GetLinkURL(int id)
    {
        return m_UrlLookup.ContainsKey(id) ? m_UrlLookup[id] : string.Empty;
    }

    static string GetLinkURL(string stringID)
    {
        int id = Int32.Parse(stringID);

        return m_UrlLookup.ContainsKey(id) ? m_UrlLookup[id] : string.Empty;
    }
}

In this above example, the URL is hardcoded but this URL could come from anywhere.

Since we are trying to get away from using long link IDs, using the URL as the dictionary key would defeat this purpose so instead we compute a unique hashcode for this URL which we use as the key. We use a custom hashcode function because we need this hashcode to be persistent (ie. always the same given the same URL).

The AddURL() function handles computing our unique hashcode for each url which is used as our unique link ID and key for our dictionary.

In Awake() we add our URL to our dictionary and then compose some text string for this url with unique link id.

The GetLinkURL() function allows us to easily retrieve the URL using our Link ID / dictionary key.

In the Update function, we simply check if the mouse if over the text object. If we are, we then check if we intersect with a link. If we do, we get the linkInfo which allows us to easily get our linkID, link text and link URL.

The above is a quick example of how we can use a dictionary to store unique integer based link IDs thus allowing us to get around the linkID length limitation and without any performance impact.

In summary, getting around this length limitation for linkID basically comes down to computing a hashcode for the url which is used as the unique linkID and key in our dictionary to track it.