Adding a "share to mastodon" link to any web site
Tags: mastodon, javascript, sharing
Published: 2023-08-17 22:09:41

---
title: Adding a "share to mastodon" link to any web site
published: true
description: 
tags: mastodon, javascript, sharing 
# cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flv75zqo2o0gtj1ew543.png
# Use a ratio of 100:42 for best results.
# published_at: 2023-08-02 09:49 +0000
---

I just added a "share to mastodon" link to my blog at [ChristianHeilmann.com](https://christianheilmann.com). Ages ago I added a "share to Twitter" link, as there is a URL you can send Tweet content to that works:

http://twitter.com/share?url={URL}&text={text}?&via={twitter_handle}

With Mastodon, it wasn't as easy as it is a federated service and there is not one URL. So I had to find a way to ask people for their service URL, and then store it somehow. 

I've seen quite a few solutions for this, but I really wanted a bare-bones one that you can style any way you want. So here's [mastodon-share](https://github.com/codepo8/mastodon-share) for you.

The first time you hit the button, it asks you for your instance. Once you defined one, clicking the button will now open a new tab with the title and the URL of the page as a, uhm, toot? 

![Screen recording of the interaction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qr7zomqc0rhurop1vhhq.gif)

In order to add a "share to mastodon" link, all you need to do is to add a link with the class ".mastodon-share" and include the script:

```HTML
<a href="#" target="mastodon" class="mastodon-share">
Share to Mastodon
</a>
<script src="mastodon-share.js"></script>
```

You can also customise all the different texts and things displayed in the interaction as data attributes:

```HTML
<a href="#" 
    target="mastodon" 
    data-prompt="Please tell me your Mastodon instance" 
    data-edittext="✏️" 
    data-editlabel="Edit your Mastodon instance" 
    class="mastodon-share">
    Share to Mastodon
</a>
```


The gist of the script is ridiculously simple, if you check it out:

``` Javascript
// Grab link from the DOM
const button = document.querySelector('.mastodon-share');

// When a user clicks the link
button.addEventListener('click', (e) => {

// If the user has already entered their instance and it is in localstorage
// write out the link href with the instance and the current page title and URL
if(localStorage.getItem('mastodon-instance')) {
  button.href = `
    https://${localStorage.getItem('mastodon-instance')}/
    share?text=${encodeURIComponent(document.title)}
    %0A${encodeURIComponent(location.href)}
  `;
// otherwise, prompt the user for their instance and save it to localstorage
} else {
    e.preventDefault();
    let instance = window.prompt(
      'Please tell me your Mastodon instance'
    );
    localStorage.setItem('mastodon-instance', instance);
}
});
```
You can [try it out on GitHub](https://codepo8.github.io/mastodon-share/).

On my blog, I use Wordpress and thus wanted to make the links also work when JavaScript fails for some reason, so I am using a slightly different approach. The PHP is:

```PHP
<p class="mastodonshare">
  <a class="tootshare" 
     href="https://mastodon.social/share?text=<?php 
            echo get_the_title()).' '.
            urlencode(the_permalink());
     ?>" target="blank" rel="noreferrer noopener">
       Share on Mastodon <span>(needs instance)</span>
  </a>
</p>
```

In the JavaScript, I also remove the span once the instance is stored in LocalStorage:

```JavaScript
const button = document.querySelector('.tootshare');
    let key = 'mastodon-instance';
    let prompt = 'Please tell me your Mastodon instance';

    if(localStorage.getItem(key)) {
        button.querySelector('span').remove();
    }

    button.addEventListener('click', (e) => {
    if(localStorage.getItem(key)) {
    button.href = button.href.replace(
        "mastodon.social", 
        localStorage.getItem(key)
    );

    } else {
        e.preventDefault();
        let instance = window.prompt(prompt);
        localStorage.setItem(key, instance);
        button.querySelector('span').remove();
    }
});
```