Create a JavaScript plugin to highlight and tweet text
Tags: javascript, tutorial, beginners, codenewbie
Published: 2020-03-23 00:09:55

---
canonical_url: https://inspiredwebdev.com/highlight-text-to-tweet
---

> This article was originally posted on my [blog](https://inspiredwebdev.com/highlight-text-to-tweet). Head over to [inspiredwebdev.com](https://inspiredwebdev.com) for more articles and tutorials. Check out my **JavaScript course** on [Educative](https://www.educative.io/courses/complete-guide-to-modern-javascript?aff=BqmB) to learn everything from ES6 to ES2019.

&nbsp;

Hi, I am Alberto Montalesi, a full-stack self-taught developer. I create JavaScript tutorials and courses on my website [inspiredwebdev.com](https://inspiredwebdev.com) to inspire other developers to grow and build the career that they want.

## Create a plugin to highlight and tweet text

Many times I found myself reading a passage on a website and thinking I wanted to share that with my friends or random people of the internet, but few are the times where the website facilitated that process for me.

Usually, I would have to copy the passage I wanted to share, go on Twitter and tweet it but we all know that most people are lazy so, if you want your user to tweet content from your articles/blogs, etc... in this tutorial, I will teach you how to create a simple plugin to do that.

Alternatively, if you don't want to bother with coding it yourself, I've already packaged it for you and you can find it on npm at <a eventLabel="link_npm_highlight" target="_blank" href="https://www.npmjs.com/package/highlight-to-tweet">highlight-to-tweet</a>.

Credits for most of the idea and the code go to this user on <a target="_blank" href="https://webflow.com/website/Highlight-text-to-Tweet-it">WebFlow</a>. I mostly transformed the JQuery code into a native `JavaScript` code and published it as an npm package.

The plugin we are going to build will work in the following way:

- A user highlight some text on your page
- They are prompted to tweet it with a button
- They click the button and they can tweet it, all without leaving your site

&nbsp;

## Create the tweetHighlighted function

Now that you are ready to start, let's open your `JavaScript` file and start with:

```javascript
document.addEventListener('DOMContentLoaded', () => {

    window.tweetHighlighted = () => {
        // our function will be built here
    }

    // we call it once the page loads
    window.tweetHighlighted()
})
```

The first thing we want to do know is to define some properties that will come in handy later on. Inside of the ` window.tweetHighlighted = () => {` function, we want to add this code:

```javascript
const settings = {
    node: "<a href='#'>Tweet</a>",
    maxLength: 280,    
    extra: null,
    via: null,
    popupArgs:'width=400,height=400,toolbar=0,location=0',
}
```

These are the basic settings of our plugin:

- node defines the element that will be contained in the button that pops up
- maxLength is the max length allowed for the tweet, here I've set it as 280 because that's the max allowed for a tweet, but if you want to set it lower you can do it
- extra is simply some extra text that you want to include in your tweets
- via defines the handler for twitter, if you want to be tagged whenever a user tweets something from your site
- popupArgs is used to define the twitter popup

Our next step will be to create a button, add it to the DOM and give an event listener to it.

Continuing after the code we just wrote, add this:

```javascript
let url = '';
let text = '';
const shareButton = document.createElement('div');
shareButton.style.display = 'none';
shareButton.addEventListener('click', (e) => {
    e.preventDefault();
    e.stopPropagation();
    window.open(url, '_blank', settings.popupArgs);
})
const body = document.querySelector('body');
body.appendChild(shareButton);
```

Firstly, we defined two empty variables that will hold our `url` and `text` for the tweet.

Secondly, we created a new `div` element and assign it to our variable `shareButton`.

We then hid it with `display:'none'` and added an event listener to it to listen for `click` events.

When a user clicks our button we use `stopPropagation` to avoid the click event to bubble down to the `a` tag that we assigned above to the `node` in our settings and we also call `window.open` passing the `url` that will be populated later and our arguments to define the size of the window to open.

After that, we are simply adding this newly created element to the `body` of our page.

One thing you may be wondering is how we are going to identify when the user highlights texts on the page.

The answer to that is simple, we will use the `mouseup` event and check if the user selected something.

&nbsp;

## Add event listeners to the function

Continuing from where we left, let's add this code:

```javascript
document.addEventListener('mouseup', (e) => {
    text = getSelectedText();
    const btnExists = shareButton.style.display !== 'none';
    if (btnExists || !text.length){
        return;
    } else {
        appendShareButton(e)
    }
})

 const getSelectedText = () => {
    if (window.getSelection) {
        return window.getSelection().toString();
    } else if (document.selection) {
        return document.selection.createRange().text;
    }
    return '';
};
```

Awesome, these two functions will ensure that when the user triggers the `mouseup` event, if there is some text highlighted, we will capture it, store it in our `text` variable and call the function `appendShareButton` to add that button to the DOM.

Let's continue and define that function:

```javascript
const appendShareButton = (e) => {
               
    url = getTweetURL(text, settings.extra, settings.via);

    shareButton.innerHTML = '';
    shareButton.innerHTML += settings.node;
    shareButton.innerHTML += tweetIcon;
    if(settings.cssClassess && settings.cssClassess.length){
        shareButton.classList.add(settings.cssClassess);
    }
    shareButton.style.top = `${e.pageY}px`;
    shareButton.style.left = `${e.pageX}px`;
    shareButton.style.position = 'absolute';
    shareButton.style.cursor = 'pointer';
    shareButton.style.display = 'flex';
    shareButton.style.justifyContent = 'space-between';
    shareButton.style.alignContent = 'center';
    shareButton.style.alignItems = 'center';
    shareButton.style.opacity = 0;

    shareButton.style.fontFamily = 'Arial, Helvetica, sans-serif';
    shareButton.style.backgroundColor = '#3898EC';
    shareButton.style.padding = '10px 15px';
    shareButton.style.width = '100px'
    shareButton.style.borderRadius = '5px';
    shareButton.style.color = 'white';
    shareButton.firstChild.style.color = 'white';
    shareButton.firstChild.style.textDecoration = 'none';
    shareButton.lastChild.style.fill = 'white';
}
```

Wow, that is a long function but don't worry, it does not do much. Most of those lines are just styling.

Firstly, we get the create the complete `url` by calling yet another function that we haven't defined, called `getTweetURL`, passing it the highlighted text, the extra text and the via handler.

We then define a list of styles on our `shareButton` to display it and position it appropriately.

The only important ones are the one relative to the positioning of the button, everything else is purely styling.

It may be gross to define each style on a different line like this but I figured it would be clearer for you to see. If you want, you can define styles this way too:

```javascript
shareButton.style.cssText = `
/* your list of style here, same as how you would add it in a CSS file*/
`
```

You may have noticed this line: `shareButton.innerHTML += tweetIcon;`

We haven't defined yet a `tweetIcon` so let's go outside this function and copy this code:

```javascript
 const tweetIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/></svg>`;
```

This is the tweet icon, it's a simple SVG I've found online, this will allow us to don't have to call it from a CDN or somewhere else.

Awesome, now we have a function to append the button to the DOM, we only need to define that function `getTweetURL`. 

Let's do that now:

&nbsp;

## Construct the URL for the tweet

```javascript
const getTweetURL = function (text, extra, via) {
    let url = 'https://twitter.com/intent/tweet?text=';
    // trim the text to fit in the max allowed 280 characters
    const viaUrl = `&via=${via}`;
    const maxLength = settings.maxLength > 280 ? 280 : settings.maxLength;
    const maxAllowedLength = maxLength - viaUrl.length - extra.length;
    let textToTweet = text;
    if(text.length > maxAllowedLength){
        textToTweet = text.substring(0,maxAllowedLength -1);
    }
    url += encodeURIComponent(textToTweet);
    if (extra)
        url += encodeURIComponent(' ' + extra);

    if (via)
        url += viaUrl

    return url;
    };
```

Let's break down this function:

- first, we define the base URL that we need
- then we create the portion of URL that contains our `via` handler
- after that, we calculate how many characters in our text allowed to take, based on the maxLength we defined (or the max of 280), the via handler and the extra text
- if the text is too long, we use `substring` to take only a portion of it
- we then stick everything together and use `encodeURIComponent` to ensure all characters are escaped properly

There you have it, this function returns a perfect URL to share the tweet.

Now you can try this code on your webpage and you will see that everything should work fine.

If you want a more customizable plugin you can check out the one i've published on <a target="_blank" href="https://github.com/AlbertoMontalesi/highlight-to-tweet">Github</a>.

&nbsp;

---

Thank you very much for reading. Follow me on [DevTo](https://dev.to/albertomontalesi) or on my blog at [inspiredwebdev](https://inspiredwebdev.com/) or on [twitter](https://twitter.com/montalesi). Check out [Educative.io](https://www.educative.io/explore?aff=BqmB) for interactive programming courses. 

Disclaimer: Links to Amazon and Educative are affiliate links, purchases you make will generate extra commissions for me. Thank you

<div className="promotional_banner">
<a href="http://a-fwd.to/5gUojI8" target="_blank">
<img alt="book banner" src="https://raw.githubusercontent.com/AlbertoMontalesi/The-complete-guide-to-modern-JavaScript/master/assets/banner.jpg" />
</a>
<span>Get my ebook on <a href="http://a-fwd.to/5gUojI8" target="_blank">Amazon</a> and <a href="https://leanpub.com/thecompleteguidetomodernjavascript2019" target="_blank">Leanpub</a></span>
</div>