Coder Social home page Coder Social logo

anantoghosh / react-linkify-it Goto Github PK

View Code? Open in Web Editor NEW
47.0 1.0 3.0 583 KB

A tiny react package that turns urls (with i18n and emoji support), emails, jira tickets, twitter handles, anything you want! in your text clickable (aka linkify).

License: MIT License

JavaScript 11.94% TypeScript 88.06%
react-linkify react linkify link url autolink text tag

react-linkify-it's Introduction

react-linkify-it ๐Ÿ”—

Npm version Build NPM bundle size Tree shaking supported Maintainability Test Coverage Known Vulnerabilities Security Score

Support me on Github Support me on KoFi

A tiny and dependency free universal linking solution that turns any pattern in your text into clickable links (aka linkify). Supports i18n and emojis.

react-linkify-it comes with a set of prebuilt components for specific linking needs and a generic component to wrap any pattern with a component.

Prebuilt components for linking:

  • URLs
  • Jira Tickets
  • Twitter usernames
  • Emails

You can also use the generic component which lets you support your own use case as desired:

  • Link GitHub Issues
  • Link tags to any social media
  • Link email addresses
  • Link phone numbers
  • Link any pattern you want!
  • Wrap any pattern with a component!

Features

  • ๐Ÿ“ฆ Tiny - Less than 800 bytes gzipped after tree shaking.
  • ๐Ÿ”น Dependency free - No extra dependencies. Just a single file.
  • ๐Ÿ“ Customizable - Adjust to your specific case as required.
  • ๐Ÿ’ง Generic - Not just links, wrap any pattern with any component.
  • ๐ŸŽ Fast - Single pass processing.
  • ๐Ÿฆบ Safe - Sanitized urls to prevent any XSS attacks.
  • ๐ŸŒ i18n - Works with urls that contain international characters.
  • โš” Tested - Thoroughly.
  • ๐Ÿ•ธ React support - Works with react v16.2+

Notes

  • react-linkify-it provides a modern bundle for actively maintained browsers and a larger legacy bundle for older browsers.
    Read about how to utilize them.

Demo

Code Sandbox

Installation

npm i react-linkify-it

Usage - Prebuilt Components

Every prebuilt component also optionally accepts a className to attach to the link wrapper

1. Urls

import { LinkItUrl } from 'react-linkify-it';

const App = () => (
  <div className="App">
    <LinkItUrl>
      <p>"add some link https://www.google.com here"</p>
    </LinkItUrl>
  </div>
);

2. Jira Tickets

import { LinkItJira } from 'react-linkify-it';

const App = () => (
  <div className="App">
    <LinkItJira domain="https://projectid.atlassian.net">
      hello AMM-123 ticket
    </LinkItJira>
  </div>
);

3. Twitter handles

import { LinkItTwitter } from 'react-linkify-it';

const App = () => (
  <div className="App">
    <LinkItTwitter>
      hello @anantoghosh twitter
    </LinkItTwitter>
  </div>
);

4. Emails

import { LinkItEmail } from 'react-linkify-it';

const App = () => (
  <div className="App">
    <LinkItEmail>
      hello [email protected] email
    </LinkItEmail>
  </div>
);

Usage - Generic Component

import { LinkIt } from 'react-linkify-it';

const regexToMatch = /@([\w_]+)/;

const App = () => (
  <div className="App">
    <LinkIt
      {/* Component to wrap each match with */}
      component={(match, key) => <a href={match} key={key}>{match}</a>}
      regex={regexToMatch}
    >
      www.google.com<div>hi @anantoghosh</div>
    </LinkIt>
  </div>
);
  • match - regex match text
  • key - unique key for the match

Usage - Generic Function

import { linkIt, UrlComponent } from 'react-linkify-it';

const regexToMatch = /@([\w_]+)/;

const App = () => {

  const output = linkIt(
    // Text to be linkified
    text,
    // Component to wrap each match with, can be any React component
    (match, key) => <UrlComponent match={match} key={key} />,
    regexToMatch
  );

  return <div className="App">{output}</div>
};
  • match - regex match text
  • key - unique key for the match

Using multiple matches

Just use more than one component to match multiple patterns.

import { LinkItEmail, LinkItUrl } from 'react-linkify-it';

const App = () => (
  <div className="App">
    <LinkItUrl>
      <LinkItEmail>
        hello [email protected] https://google.com
      </LinkItEmail>
    </LinkItUrl>
  </div>
);

Using modern and legacy bundle

By default, when you import react-linkify-it, it will use a modern bundle meant for browsers which support RegExp Unicode property escapes.

If you are using babel-preset-env, or any bundler configuration which uses it (e.g. create-react-app, vite) with a browser which does not support RegExp Unicode property escapes, babel will transform the code to support the browsers resulting in a larger bundle.

If your setup does not use babel-preset-env and you would still like to support older browsers, you can use the legacy bundle by importing:

For javascript projects

import { linkIt, LinkIt } from "react-linkify-it/legacy";

For typescript < v5.0.0 projects (why?)

import { linkIt, LinkIt } from "react-linkify-it/dist/react-linkify-it.legacy.esm.min";

Note: Legacy bundle has a larger file size (~3.4Kb minziped).

Using a browser bundle

An umd build with legacy browser support can be used from Unpkg.

Acknowledgment

This project was made possible due to the incredible work done on the following projects:

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Hey ๐Ÿ‘‹ If my packages has helped you in any way, consider making a small donation to encourage me to keep contributing. Maintaining good software takes time and effort and for open source developers there is very less incentives to do so. Your contribution is greatly appreciated and will motivate me to continue to support developing my packages which you may have used.

Support me on Github Support me on KoFi

react-linkify-it's People

Contributors

anantoghosh avatar evgeniy-ferapontov avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

react-linkify-it's Issues

Maybe can we create a wiki of common regex patterns

That might be cool to help others pick. Maybe with examples that pattern matches. Like two table column. I can see not wanting to do this, and closing this issue. Just a thought as I was struggling with the phone.

I'm using this pattern for phone I found here https://stackoverflow.com/q/4338267/1828637 , but not sure if it's right as it misses +1 (999) 999-9999.

const phoneRegex = /\+?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4,6}/;

Not working on contentEditable component

When I try to use react-linkify-it to wrap a contentEditable component it does not render a tag;

code example:
<LinkItUrl> <LinkItEmail> <div contentEditable={true} /> </LinkItEmail> </LinkItUrl>

image

URL regex causing syntax errors in mobile safari

This regex here is causing a syntax error in some browsers.

export const urlRegex =
/(https?:\/\/|www\.)([-\w.]+\/[\p{L}\p{Emoji}\p{Emoji_Component}!#$%&'"()*+,./\\:;=_?@[\]~-]*[^\s'",.;:\b)\]}?]|(([\w-]+\.)+[\w-]+[\w/-]))/u;

The error is:

Invalid regular expression: invalid escaped character for unicode pattern

The browsers I got errors in so far are:

Mobile Safari 10.0
Mobile Safari 13.1.2

I'm not sure how to fix it exactly. :(

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore(deps): lock file maintenance

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • chore(deps): update dependency eslint to v9
  • chore(deps): update dependency np to v10
  • chore(deps): update github artifact actions to v4 (major) (actions/download-artifact, actions/upload-artifact)
  • chore(deps): update paambaati/codeclimate-action action to v6
  • chore(deps): update pnpm to v9
  • chore(deps): update testing-library monorepo (major) (@testing-library/jest-dom, @testing-library/react)
  • chore(deps): update typescript-eslint monorepo to v7 (major) (@typescript-eslint/eslint-plugin, @typescript-eslint/parser)
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/node.js.yml
  • actions/checkout v3
  • actions/setup-node v3
  • actions/cache v3
  • paambaati/codeclimate-action v3.2.0
.github/workflows/npm-publish.yml
  • actions/checkout v3
  • actions/setup-node v3
  • actions/upload-artifact v3
  • actions/checkout v3
  • actions/setup-node v3
  • actions/download-artifact v3
  • actions/checkout v3
  • actions/setup-node v3
  • actions/download-artifact v3
nodenv
.node-version
  • node 16.20.2
npm
package.json
  • @babel/core ^7.22.10
  • @babel/plugin-proposal-nullish-coalescing-operator ^7.18.6
  • @babel/plugin-transform-runtime ^7.22.10
  • @babel/preset-env ^7.22.10
  • @babel/preset-typescript ^7.22.5
  • @babel/runtime ^7.22.10
  • @rollup/plugin-terser ^0.4.3
  • @testing-library/jest-dom ^5.17.0
  • @testing-library/react ^14.0.0
  • @types/jest ^27.5.2
  • @types/react ^18.2.20
  • @types/testing-library__jest-dom ^5.14.9
  • @typescript-eslint/eslint-plugin ^6.3.0
  • @typescript-eslint/parser ^6.3.0
  • eslint ^8.47.0
  • eslint-plugin-tree-shaking ^1.10.0
  • jest ^27.5.1
  • np ^8.0.4
  • prettier ^3.0.1
  • react ^18.2.0
  • react-dom ^18.2.0
  • rollup ^3.28.0
  • rollup-plugin-size ^0.3.1
  • rollup-plugin-ts ^3.4.4
  • ts-jest ^27.1.5
  • tslib ^2.6.1
  • typescript ~4.9.5
  • react *
  • pnpm 8.7.6

  • Check this box to trigger a request for Renovate to run again on this repository

Missing urls like youtube.com

Is there reason you chose to not catch like youtube.com? Or should we try to find a regex that gets it too? This component I'm using:

const Linkify = memo((props: ILinkifyProps) => {
  return (
    <LinkItPhone>
      <LinkItUrl>
        <LinkItEmail>{props.children}</LinkItEmail>
      </LinkItUrl>
    </LinkItPhone>
  );
});

Linkify.displayName = 'Linkify';

const phoneRegex = /\+?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4,6}/;
const phoneLinkComponent = (match: string, key: number) => (
  <a href={'tel:' + match.replace(/\D/g, '')} key={key}>
    {match}
  </a>
);
const LinkItPhone = memo((props: { children: StrictReactNode }) => {
  return (
    <LinkIt component={phoneLinkComponent} regex={phoneRegex}>
      {props.children}
    </LinkIt>
  );
});
LinkItPhone.displayName = 'LinkItPhone';

Single component to get the typical stuff, links, emails, phones

Thanks very much for this. It was badly needed. Everyone is using the unmaintained react-linkify and it has bugs.

I do miss the ease of react-linkify, where it got all the things you expected it to (links, phone, email - not jira, twitter, mentions etc), and could easily add properties like "target" blank, which you have, but just as example.

Is there a chance for a simpler linke-what-you-expect component?

from, not form

the readme contains import statements using form like:

import { LinkItUrl } form 'react-linkify-it';

which gives error :)

Is the special esm import needed?

I'm using Next.js and node 14. I was trying to use that import style but it wouldn't work. I don't have the error right now but I can get it. I'm using Typescript.

I changed

import { LinkIt } from "react-linkify-it/dist/react-linkify-it.legacy.esm.min";

To:

import {LinkIt} from 'react-linkify-it';

And it started working. If not needed anymore, I would love to provide PR to remove it from readme.

className doesn't appear to work

can't get className to pass into components. Appears to neither be a property of LinkItUrl nor work when specified via the component function per the docs.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.