DEV Community

Christian Heilmann
Christian Heilmann

Posted on

Adding a "share to mastodon" link to any web site

I just added a "share to mastodon" link to my blog at 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 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

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:

<a href="#" target="mastodon" class="mastodon-share"> Share to Mastodon </a> <script src="mastodon-share.js"></script> 
Enter fullscreen mode Exit fullscreen mode

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

<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> 
Enter fullscreen mode Exit fullscreen mode

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

// 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); } }); 
Enter fullscreen mode Exit fullscreen mode

You can try it out on GitHub.

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:

<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> 
Enter fullscreen mode Exit fullscreen mode

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

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(); } }); 
Enter fullscreen mode Exit fullscreen mode

Top comments (1)