Christian Heilmann

Adding a “share to mastodon” link to any web site – and here

Friday, August 18th, 2023 at 11:00 am

I just added a “share to mastodon” link to this bloh. 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.

Mastodon Share

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" rel="noopener">
Share to Mastodon
</a>
<script src="mastodon-share.js"></script>

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);
}
});

(yes, the comments were generated by GitHub CoPilot).

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>

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();
    }
});

Hope that helps!

I also came across the mastodon-share button by grayleonard that uses an input field on the button to allow you to specify the instance, but doesn’t store it. It looks nicer, though.

You can also use toot.kytta.dev to avoid having to request the mastodon instance people want to use, but I didn’t want to rely on another service.

Share on Mastodon (needs instance)

Share on Twitter

My other work: