# Creating Dynamic Hyperlinked Text Components in VUE JS

### **Introduction**

When building modern web applications, there are many instances where you need to dynamically insert hyperlinks into a block of text. Whether you’re parsing user-generated content or just want to ensure all URLs in a given string are clickable, having a reusable component to handle this task efficiently is crucial. In this blog post, we'll walk through how to create a dynamic Vue.js component that automatically detects and transforms URLs in a string into clickable hyperlinks. This component will also handle text formatting, like adding line breaks, to ensure the content displays as expected.

### **Why Dynamic Hyperlinking?**

Imagine you have a text string that includes URLs. Without the right component, you’d need to manually find and wrap each URL in an `<a>` tag. This can be error-prone, especially when dealing with large blocks of text or user-generated content. A dynamic hyperlinking component simplifies this process by automatically detecting URLs and converting them into clickable links, which enhances user experience and ensures consistency.

#### **The Code Explained**

Let's break down the code to understand how this component works and why it's beneficial.

```javascript
import { h } from "vue"

export default {
    props: {
        tag: {
            type: String,
            required: true,
            default: "p",
        },
        text: {
            type: String,
            default: null,
        },
        className: {
            type: [String, Array],
            required: false,
            default: "",
        },
        hyperLinkClass: {
            type: [String, Array],
            required: false,
            default: "",
        },
    },
    setup(props) {
        const addHttps = (url) => {
            return url.startsWith("http://") || url.startsWith("https://")
                ? url
                : `https://${url.startsWith("www.") ? "" : "www."}${url}`
        }

        const urlRegex = /\b(?:https?:\/\/|www\.)\S+\b/gi

        const processText = (text) => {
            const parts = []
            let lastIndex = 0
            let match

            while ((match = urlRegex.exec(text)) !== null) {
                if (lastIndex < match.index) {
                    parts.push(text.slice(lastIndex, match.index))
                }
                parts.push(h("a", {
                    href: addHttps(match[0]),
                    target: "_blank",
                    class: props.hyperLinkClass,
                }, match[0]))
                lastIndex = urlRegex.lastIndex
            }

            if (lastIndex < text.length) {
                parts.push(text.slice(lastIndex))
            }

            return parts
        }

        const lines = props.text ? props?.text?.split("\n") : []
        const children = lines.reduce((accumulator, line, index) => {
            const lineElements = processText(line)

            if (index > 0) {
                accumulator.push(h("br"))
            }

            return accumulator.concat(lineElements)
        }, [])

        return () => h(
            props?.tag,
            {
                class: props?.className,
            },
            children,
        )
    },
}
```

##### **Component Structure**

* **Props Configuration:**
    
    * **tag:** Defines the HTML tag (like `p`, `div`, or `span`) that will wrap the content. This adds flexibility, allowing the component to be used in various contexts.
        
    * **text:** The string containing the text that may include URLs. This will be processed to identify and link the URLs.
        
    * **className:** This allows passing custom classes to style the component as needed.
        
    * **hyperLinkClass:** Defines the class to style the generated hyperlinks. By default, it ensures the links are visually consistent with the rest of the design.
        

##### **Core Functionality:**

* **addHttps Function:** This function ensures that all URLs start with `https://` or `http://`. If a URL lacks these protocols, `https://` is prepended. This guarantees that all links are valid and clickable.
    
* **urlRegex:** A regular expression `regex` is used to detect URLs in the text. The `regex` identifies strings that start with "http://", "https://", or "[www](http://www)." and treats them as URLs.
    
* **processText Function:** This is where the magic happens. It splits the input text into chunks, identifies URLs, wraps them in `<a>` tags, and returns the processed content. This function is robust enough to handle multiple URLs within the same text.
    
* **Lines Processing:** The text is split into lines to preserve any line breaks. Each line is processed individually to find and wrap URLs, ensuring that the formatting remains intact.
    
* **Dynamic Rendering:** The component dynamically renders the processed text within the specified HTML tag, applying the relevant styles.
    

#### **How to Use the Component**

Once you’ve set up this component, you can easily use it in your Vue.js application:

```javascript
<HyperlinkedText 
    tag="p" 
    :text="`Check out this website: www.example.com and also this one: https://www.another-example.com`" 
    className="my-custom-class" 
    hyperLinkClass="custom-link-class" 
/>
```

This will render a paragraph where the URLs are automatically hyperlinked and styled with your custom classes.

#### **Benefits**

* **Efficiency:** Automatically finds and hyperlinks URLs without manual intervention.
    
* **Flexibility:** Use any HTML tag and customize the styles as needed.
    
* **User Experience:** Enhances the readability and interactivity of text, ensuring users can easily click on links.
    

#### **Conclusion**

This dynamic hyperlinking component is a powerful tool for any Vue.js developer. By automatically detecting and linking URLs, it saves time and ensures consistency across your application. Whether you’re handling user-generated content or simply want to streamline your content management process, this component is a valuable addition to your toolkit.

With this component in place, you can confidently manage text with embedded links, providing a seamless and user-friendly experience.

Feel free to share your thoughts and opinions and leave me a comment if you have any problems or questions. 😎😎

I hope you liked it and learned something!

Happy Coding!!
