Adding a Mastodon link to Gatsby posts
Table of Contents
One thing that's unusual about Mastodon is the server is not always the same. Most of the time, people are on Mastodon.social, but here's how you can account for this.
§ Setting up Share Links for Facebook and Twitter
A preview of the full code can be viewed here.
import FacebookSvg from 'assets/social/facebook.svg';
import TwitterXSvg from 'assets/social/x-twitter.svg';
import MastadonSvg from 'assets/social/mastadon.svg';
const SocialLinks = () => {
const url = typeof window !== 'undefined' ? window.location.href : '';
const openInNewTab = (dynamicUrl: any) => {
window.open(
dynamicUrl + url,
'\_blank',
'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=300,width=600',
);
};
const handleFBUrl = () => {
const fbUrl = 'https://www.facebook.com/sharer/sharer.php?u=';
openInNewTab(fbUrl);
};
const handleTwitterUrl = () => {
const twitterUrl = 'https://twitter.com/share?url=';
openInNewTab(twitterUrl);
};
const handleMastadonUrl = () => {
const openMastodon = () => {
openInNewTab(
'https://' +
localStorage.getItem('mastodon-instance') +
'/share?text=' +
encodeURIComponent(document.title) +
'%0A' +
url,
);
};
if (localStorage.getItem('mastodon-instance')) {
openMastodon();
} else {
let instance = window.prompt('Please tell me your Mastodon instance');
if (instance) {
localStorage.setItem('mastodon-instance', instance);
openMastodon();
}
}
};
return (
<div className="d-flex">
<a href="#" title="Share on Facebook" onClick={handleFBUrl}>
<FacebookSvg className="socialIcon regularIcon linkIcon" />
</a>
<a href="#" title="Share on Twitter" onClick={handleTwitterUrl}>
<TwitterXSvg className="socialIcon regularIcon linkIcon" />
</a>
<a href="#" title="Share on Mastadon" onClick={handleMastadonUrl}>
<MastadonSvg className="socialIcon regularIcon linkIcon" />
</a>
</div>
);
};
export default SocialLinks;
Let's deconstruct the code a little. This assumes you have a component that contains all your share links.
Let's call our component ShareLinks and include a helper function at the beginning.
const url = typeof window !== 'undefined' ? window.location.href : '';
const openInNewTab = (dynamicUrl: any) => {
window.open(
dynamicUrl + url,
'_blank',
'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=300,width=600',
);
};
Next we account for the main social media accounts which utilize the openInNewTab helper function:
const handleFBUrl = () => {
const fbUrl = 'https://www.facebook.com/sharer/sharer.php?u=';
openInNewTab(fbUrl);
};
const handleTwitterUrl = () => {
const twitterUrl = 'https://twitter.com/share?url=';
openInNewTab(twitterUrl);
};
This function receives a URL such as Facebook or Twitter, and returns a pop-up window respectively.
So the corresponding div will call on handleFBUrl
to fire.
<a href="#" title="Share on Facebook" onClick={handleFBUrl}>
<FacebookSvg className="socialIcon regularIcon linkIcon" />
</a>
§ Setting up Share Link for Mastodon
To set up a Mastodon link, I borrowed heavily from this post on Dev.to from Christian Heilmann.
We're going to use localStorage
on the user's browser to keep this information handy. (Usage of localStorage
does not require the user's permission.)
First, we're going to write another helper function, this time one that calls to retrieve a variable named 'mastodon-instance'.
const handleMastadonUrl = () => {
const openMastodon = () => {
openInNewTab(
'https://' +
localStorage.getItem('mastodon-instance') +
'/share?text=' +
encodeURIComponent(document.title) +
'%0A' +
url,
);
};
Of course, we don't want to retrieve this variable if it doesn't exist on the user's computer yet, so we are going to check for it, and ask the user for it if it's unavailable.
if (localStorage.getItem('mastodon-instance')) {
openMastodon();
} else {
let instance = window.prompt('Please tell me your Mastodon instance');
if (instance) {
localStorage.setItem('mastodon-instance', instance);
openMastodon();
}
}
The prompt should look something like this:
The entire code is provided below:
import FacebookSvg from 'assets/social/facebook.svg';
import TwitterXSvg from 'assets/social/x-twitter.svg';
import MastadonSvg from 'assets/social/mastadon.svg';
const SocialLinks = () => {
const url = typeof window !== 'undefined' ? window.location.href : '';
const openInNewTab = (dynamicUrl: any) => {
window.open(
dynamicUrl + url,
'\_blank',
'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=300,width=600',
);
};
const handleFBUrl = () => {
const fbUrl = 'https://www.facebook.com/sharer/sharer.php?u=';
openInNewTab(fbUrl);
};
const handleTwitterUrl = () => {
const twitterUrl = 'https://twitter.com/share?url=';
openInNewTab(twitterUrl);
};
const handleMastadonUrl = () => {
const openMastodon = () => {
openInNewTab(
'https://' +
localStorage.getItem('mastodon-instance') +
'/share?text=' +
encodeURIComponent(document.title) +
'%0A' +
url,
);
};
if (localStorage.getItem('mastodon-instance')) {
openMastodon();
} else {
let instance = window.prompt('Please tell me your Mastodon instance');
if (instance) {
localStorage.setItem('mastodon-instance', instance);
openMastodon();
}
}
};
return (
<div className="d-flex">
<a href="#" title="Share on Facebook" onClick={handleFBUrl}>
<FacebookSvg className="socialIcon regularIcon linkIcon" />
</a>
<a href="#" title="Share on Twitter" onClick={handleTwitterUrl}>
<TwitterXSvg className="socialIcon regularIcon linkIcon" />
</a>
<a href="#" title="Share on Mastadon" onClick={handleMastadonUrl}>
<MastadonSvg className="socialIcon regularIcon linkIcon" />
</a>
</div>
);
};
export default SocialLinks;