Skip to content
UI

Linkified Text

beta

Turns the live http and https URLs in a plain string into External Links and leaves defanged ones as text.

@zenoxai/ui/patterns/linkified-text Markdown

Takedown requested through on Oct 23. The kit itself is at hxxps://login-verify-acme[.]com/portal and stays text.

<p className="max-w-lg text-sm text-text-secondary">
  <LinkifiedText>
    {
      "Takedown requested through https://abuse.registrar.example/report on Oct 23. The kit itself is at hxxps://login-verify-acme[.]com/portal and stays text."
    }
  </LinkifiedText>
</p>

Usage

import { LinkifiedText } from "@zenoxai/ui/patterns/linkified-text"

<p className="text-sm text-text-secondary">
  <LinkifiedText>{comment.body}</LinkifiedText>
</p>

Use it on prose that may hold URLs: analyst comments, descriptions, report text. The text stays exactly as written; each live http or https URL becomes an External Link with its disclosure.

  • A defanged or partly defanged URL (hxxps://evil[.]example, https://paypal.com[.]evil.example) is never linked, and never trimmed into a link: in threat data it means “do not click”.
  • A host without a scheme (www.acme.example) stays text.
  • Trailing punctuation and unbalanced brackets stay outside the link, as in GitHub’s autolinks: “see https://acme.example/a).” links https://acme.example/a.

Detection is findIndicators, so the two never disagree on what a URL is. It takes a string only: Markdown and HTML need their own renderer, which can render External Link for its links. Never put Linkified Text on an indicator column or field.

Examples

Keeping indicators out

Prose about an alert often repeats its indicators. Pass isLinkable with the record’s own indicators: those URLs render in font-mono, following zx/inline-code, and never as a link.

First seen at https://login-verify-acme.com/portal, reported to .

function LinkifiedTextIndicators() {
  const indicators = new Set(["https://login-verify-acme.com/portal"])

  return (
    <p className="max-w-lg text-sm text-text-secondary">
      <LinkifiedText isLinkable={(url) => !indicators.has(url.href)}>
        {
          "First seen at https://login-verify-acme.com/portal, reported to https://abuse.registrar.example/report."
        }
      </LinkifiedText>
    </p>
  )
}

Accessibility

  • Each link follows External Link’s contract: a real link, a disclosure that takes focus, a new tab.
  • The URL is shown as written, so the link’s name is the URL the user reads.

API reference

Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.

LinkifiedText

LinkifiedText turns the live http and https URLs in a plain string into ExternalLinks and leaves the rest of the text as it is, URLs included as written. A defanged or partly defanged URL (`hxxps://`, `evil[.]com`) and a host without a scheme stay text: in threat data they mean "do not click".

PropTypeDefault
isLinkable((url: URL) => boolean)

Whether a URL may become a link. Return `false` for the indicators of the record on screen: they render as monospace text, never as a link.

-
labelsPartial<ExternalLinkLabels>

Forwarded to every link: the disclosure's translated texts.

-
underline"hover" | "always"

Forwarded to every link.

-