skip to Main Content

So I want my react code to detect every link like I type for example "http://localhost:3000/"
it gives me a formatted link and not a plain text

here is my code:

//Linkify.jsx
import DOMPurify from 'dompurify'
const Linkify = ({ children }) => {
  const isUrl = (word) => {
    const urlPattern = /^(http://www.|https://www.|http://|https://)?[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?$/gm;
    return word.match(urlPattern);
  };

  const addMarkup = (word) => {
    return isUrl(word) ? `<a class="text-blue-500 hover:text-blue-600 transition" href="${word}">${word}</a>` : `<span className="no-underline">${word}</span>`;
  };

  const words = children.split(" ");
  const formatedWords = words.map((w, i) => addMarkup(w));

  const html = DOMPurify.sanitize(formatedWords.join(' '))

  return <span  dangerouslySetInnerHTML={{ __html: html }} />;
};

export default Linkify;

import Linkify from "./Linkify"

const Test = () => {
  return (
    <div>
      <Linkify>
      http://localhost:3000/
      </Linkify>
    </div>
  )
}

export default Test
//this code gives me not a link but a plain text

Anything helps

2

Answers


  1. Chosen as BEST ANSWER

    Alright so I found answer on my problem,here is the code for detecting a link:

    import dompurify from "dompurify";
    
    
    // detects every link now
    const Linkify = ({ children }) => {
      const isUrl = (word) => {
        const urlPattern = /(https?://[^s]+)/g;
        return word.match(urlPattern);
      };
    
      const addMarkup = (word) => {
        return isUrl(word)
          ? `<a class="text-blue-500 hover:text-blue-600 transition" href="${word}">${word}</a>`
          : `<span className="no-underline text-white">${word}</span>`;
      };
    
      const words = children.split(" ");
      const formatedWords = words.map((w, i) => addMarkup(w));
    
      const html = dompurify.sanitize(formatedWords.join(" "));
    
      return <span dangerouslySetInnerHTML={{ __html: html }} />;
    };
    
    export default Linkify
    
    

  2. I replicated your code in codepen and it works fine, just the port on the URL and not having a top-level domain (TLD) which the RegEx is not picking up.

    Using your code with a regularly formatted URL works fine.

    Working Codepen Example

    import dompurify from "https://esm.sh/dompurify";
    import React from "https://esm.sh/react";
    import ReactDOM from "https://esm.sh/react-dom";
    
    const Linkify = ({ children }) => {
      const isUrl = (word) => {
        const urlPattern = /^(http://www.|https://www.|http://|https://)?[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?$/gm;
        return word.match(urlPattern);
      };
    
      const addMarkup = (word) => {
        return isUrl(word)
          ? `<a class="text-blue-500 hover:text-blue-600 transition" href="${word}">${word}</a>`
          : `<span className="no-underline">${word}</span>`;
      };
    
      const words = children.split(" ");
      const formatedWords = words.map((w, i) => addMarkup(w));
    
      const html = dompurify.sanitize(formatedWords.join(" "));
    
      return <span dangerouslySetInnerHTML={{ __html: html }} />;
    };
    
    const Test = () => {
      return (
        <div>
          <Linkify>
            Add a URL in here, for example, http://www.google.com/ -- look's good!
          </Linkify>
        </div>
      );
    };
    
    const root = ReactDOM.createRoot(document.getElementById("app"));
    
    root.render(<Test />);
    
    

    Cheers

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search