Skip to content

Instantly share code, notes, and snippets.

@JLarky
Last active September 10, 2020 08:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JLarky/f885f68f71b48f317b0eb381f2140d59 to your computer and use it in GitHub Desktop.
Save JLarky/f885f68f71b48f317b0eb381f2140d59 to your computer and use it in GitHub Desktop.
Example of automatically detecting links (http and email) in text and turning it into react components. Note I think linkifyjs detects less accurately than linkify-it and react-linkify is slightly over engineered and looked stale at the moment.
import LinkifyIt from 'linkify-it';
import tlds from 'tlds';
import React from 'react';
const linkify = new LinkifyIt();
linkify.tlds(tlds);
// based on https://github.com/tasti/react-linkify/blob/d0afedd671fd59b1d73ce5bdbadf90268824edb7/src/components/Linkify.jsx
export function parseString(
string: string,
componentDecorator: (match: LinkifyIt.Match, i: number) => React.ReactNode
): React.ReactNode {
if (string === '') {
return string;
}
const matches = linkify.match(string);
if (!matches) {
return string;
}
const elements: React.ReactNode[] = [];
let lastIndex = 0;
matches.forEach((match, i) => {
// Push preceding text if there is any
if (match.index > lastIndex) {
elements.push(string.substring(lastIndex, match.index));
}
elements.push(componentDecorator(match, i));
lastIndex = match.lastIndex;
});
// Push remaining text if there is any
if (string.length > lastIndex) {
elements.push(string.substring(lastIndex));
}
return elements.length === 1 ? elements[0] : elements;
}
import { Match } from 'linkify-it';
import React from 'react';
import { parseString } from '../vendor/linkify/linkify';
const decorateComponent = (match: Match, i: number) => (
<a
key={i}
href={match.url}
target="_blank"
rel="noopener noreferrer"
className="font-bold hover:underline"
title={match.raw}
>
{match.text}
</a>
);
export const LinkifyIt: React.FC<{ text: string }> = ({ text }) => {
return <>{parseString(text, decorateComponent)}</>;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment