Search code examples
javascriptsolid-js

How to create a post where the web links present in the content will be functional?


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!


Solution

  • 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?