0

I created a solid-js application where it is possible to create posts. I would like to ensure that when the user inserts a url link in his post that this link can be used and thus led to another web page when clicked. I would therefore like my application to be able to recognize a url in a content and turn it into a link. However, I don't know how to go about it, currently when the user inserts a url address in his post; this address is displayed in the post as a normal text namely in black and white and leads nowhere. I tried searching the internet for the solution but nothing about it. Here is my solid-js code:

<Show when={merged.content}>
        <section className="px-4 py-4 flex flex-col space-y-2">
          <p className="text-[.9375rem] text-gray-700 dark:text-gray-200">
            {merged.content}
          </p>
        </section>
      </Show>

I tried the following solution:

 <Show when={merged.content}>
        <section className="px-4 py-4 flex flex-col space-y-2">
          <div>
    <For each={merged.content.split(" ")}>
    {
        (word) => {
            if(word.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi)) {
                return <a href={word}>word</a>
            } else {
                return <p className="text-[.9375rem] text-gray-700 dark:text-gray-200">word</p>
            }
        }
    }
    </For>
</div>
        </section>
      </Show>

But instead every time I create a post no matter the content, the word word is returned as many times as there are words in that post.

Looking forward to your answers, thanks!

1 Answers1

0

This is a non-trivial problem. What you could do is dynamically build a solid component based on regex string parsing. Here's some code for how I would do it:

<div>
    <For each={merged.content.split(" ")}>
    {
        (word) => {
            if(word.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi)) {
                return <a href={word}>{word}</a>
            } else {
                return <p>{word}</p>
            }
        }
    }
    </For>
</div>

This would require some styling obviously, but it looks like you have a decent grasp of tailwind so you should be fine.

The regex I use comes from this stack overflow post: What is a good regular expression to match a URL?

IndevSmiles
  • 737
  • 6
  • 17
  • I tested your solution, but instead it replaced all the words present in my posts with the word **word** , I inserted the code in my question. Thank you and have a good evening! –  Aug 19 '22 at 21:35
  • Sorry about that, I didn't test this code. I have updated my post, does that work for you? – IndevSmiles Aug 19 '22 at 22:51
  • It's great, it works. But if I do `facebook.com` it does not create a link whereas if I do `https://facebook.com` it does create a link. Do you also have a solution for this? Thanks ! –  Aug 19 '22 at 23:11
  • Replace the regex with `/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi` – IndevSmiles Aug 19 '22 at 23:17
  • This will create a lot of false positives though. The following would trigger it: hinds.oi misspellin.g – IndevSmiles Aug 19 '22 at 23:18