Links recognition library with FULL unicode support for detecting high-quality link patterns in plain text
npx @tessl/cli install tessl/npm-linkify-it@5.0.0LinkifyIt is a links recognition library with full Unicode support for detecting high-quality link patterns in plain text. It supports international domains, astral characters, fuzzy link detection without protocols, and provides extensible rules with custom normalizers for specialized link types.
npm install linkify-itimport LinkifyIt from "linkify-it";
// Can also import as default function
import linkify from "linkify-it";For CommonJS:
const LinkifyIt = require("linkify-it");import LinkifyIt from "linkify-it";
// Create linkifier instance (works with or without 'new')
const linkify = LinkifyIt();
// Test if text contains links
const hasLinks = linkify.test("Visit github.com!");
// => true
// Extract all links from text
const matches = linkify.match("Visit github.com and https://example.com");
// => [{schema: "", index: 6, lastIndex: 16, raw: "github.com", text: "github.com", url: "http://github.com"},
// {schema: "https:", index: 21, lastIndex: 42, raw: "https://example.com", text: "https://example.com", url: "https://example.com"}]
// Configure fuzzy detection options
linkify.set({ fuzzyIP: true, fuzzyEmail: true });
// Add custom protocols
linkify.add("git:", "http:"); // Alias git: to http:
linkify.add("ftp:", null); // Disable ftp: protocolLinkifyIt is built around several key components:
Creates new linkifier instance with optional additional schemas and configuration options.
/**
* Creates new linkifier instance with optional additional schemas.
* Can be called without `new` keyword for convenience.
* @param schemas - Optional object with protocol definitions (prefix/validator pairs)
* @param options - Optional configuration options for fuzzy link detection
* @returns LinkifyIt instance
*/
function LinkifyIt(schemas?: Record<string, string | SchemaDefinition>, options?: LinkifyItOptions);
interface LinkifyItOptions {
/** Recognize URLs without http(s):// prefix. Default true */
fuzzyLink?: boolean;
/** Allow IPs in fuzzy links. Can conflict with version numbers. Default false */
fuzzyIP?: boolean;
/** Recognize emails without mailto: prefix. Default true */
fuzzyEmail?: boolean;
/** Terminate links with --- (long dash). Default false */
"---"?: boolean;
}
interface SchemaDefinition {
/** Validator function or RegExp to check tail after link prefix */
validate: ((text: string, pos: number, self: LinkifyIt) => number) | RegExp;
/** Optional function to normalize text & url of matched result */
normalize?: (match: Match, self: LinkifyIt) => void;
}Core methods for detecting and extracting links from text.
/**
* Searches linkifiable pattern and returns true on success or false on fail
* @param text - Text to search for links
* @returns Boolean indicating if link was found
*/
test(text: string): boolean;
/**
* Quick check if link MAY exist. Can give false positives but no false negatives.
* Used for speed optimization when you need to check that link NOT exists.
* @param text - Text to check
* @returns Boolean indicating if link might exist
*/
pretest(text: string): boolean;
/**
* Returns array of found link matches or null if nothing found
* @param text - Text to scan for links
* @returns Array of Match objects or null
*/
match(text: string): Match[] | null;
/**
* Returns fully-formed (not fuzzy) link if it starts at the beginning
* of the string, and null otherwise. Doesn't work with fuzzy links.
* @param text - Text to check
* @returns Match object or null
*/
matchAtStart(text: string): Match | null;
/**
* Similar to test() but checks only specific protocol tail exactly at given position
* @param text - Text to scan
* @param schema - Schema/protocol name to test
* @param position - Text offset to check from
* @returns Length of found pattern (0 on fail)
*/
testSchemaAt(text: string, schema: string, position: number): number;Chainable methods for configuring linkifier behavior and adding custom rules.
/**
* Add new rule definition or disable existing rule
* @param schema - Rule name (protocol prefix like 'skype:')
* @param definition - Schema definition, alias string, or null to disable
* @returns this (chainable)
*/
add(schema: string, definition: string | SchemaDefinition | null): LinkifyIt;
/**
* Set recognition options for links without schema
* @param options - Options object with fuzzyLink, fuzzyEmail, fuzzyIP properties
* @returns this (chainable)
*/
set(options: Partial<LinkifyItOptions>): LinkifyIt;
/**
* Load or merge new tlds list for fuzzy links (without schema) to avoid false positives
* @param list - TLD list to add (array or single string)
* @param keepOld - Whether to merge with current list (default false)
* @returns this (chainable)
*/
tlds(list: string | string[], keepOld?: boolean): LinkifyIt;Methods for customizing link processing and regex compilation.
/**
* Default normalizer for matches (can be overridden)
* Adds http:// prefix for fuzzy links and mailto: for emails
* @param match - Match object to normalize
*/
normalize(match: Match): void;
/**
* Override hook called during regex compilation
* Can be used to modify basic RegExp patterns
*/
onCompile(): void;Result object representing a single detected link.
interface Match {
/** Prefix (protocol) for matched string, can be empty for fuzzy links */
schema: string;
/** First position of matched string */
index: number;
/** Next position after matched string */
lastIndex: number;
/** Original matched text */
raw: string;
/** Normalized text of matched string */
text: string;
/** Normalized URL of matched string */
url: string;
}interface SchemaDefinition {
validate: ValidatorFunction | RegExp;
normalize?: NormalizerFunction;
}
type ValidatorFunction = (text: string, pos: number, self: LinkifyIt) => number;
type NormalizerFunction = (match: Match, self: LinkifyIt) => void;import LinkifyIt from "linkify-it";
const linkify = LinkifyIt();
// Add Twitter mention handler
linkify.add("@", {
validate: function (text, pos, self) {
const tail = text.slice(pos);
if (!self.re.twitter) {
self.re.twitter = new RegExp(
"^([a-zA-Z0-9_]){1,15}(?!_)(?=$|" + self.re.src_ZPCc + ")"
);
}
if (self.re.twitter.test(tail)) {
// Prevent @@mention (invalid)
if (pos >= 2 && text[pos - 2] === "@") {
return 0;
}
return tail.match(self.re.twitter)[0].length;
}
return 0;
},
normalize: function (match) {
match.url = "https://twitter.com/" + match.url.replace(/^@/, "");
}
});
const matches = linkify.match("Hello @username!");
// => [{schema: "@", ..., text: "@username", url: "https://twitter.com/username"}]import LinkifyIt from "linkify-it";
import tlds from "tlds"; // Full TLD list package
const linkify = LinkifyIt();
// Add custom TLD while keeping defaults
linkify.tlds("onion", true);
// Replace with full TLD list
linkify.tlds(tlds);
// Test custom domains
console.log(linkify.test("visit example.onion")); // true with custom TLD
console.log(linkify.test("check example.xyz")); // true with full TLD listimport LinkifyIt from "linkify-it";
// Create with custom options
const linkify = LinkifyIt({
fuzzyLink: true,
fuzzyEmail: true,
fuzzyIP: true,
"---": true // Terminate links at triple dash
});
// Add Git protocol as HTTP alias
linkify.add("git:", "http:");
// Disable FTP support
linkify.add("ftp:", null);
// Test various link types
console.log(linkify.match("git://github.com/user/repo.git"));
console.log(linkify.match("Contact me at user@domain.com"));
console.log(linkify.match("Server at 192.168.1.1:8080"));Error for invalid schema definitions during .add() callstest, match, pretest, etc.) return null, false, or 0 for no matches rather than throwingError with descriptive messages like "(LinkifyIt) Invalid schema 'name': reason"Error during schema compilation via .add()tlds() method accepts arrays or single strings without throwing for invalid input types