When a new year begins, I write down some goals to achieve. In 2022, one of these goals was to create a beautiful, custom Ghost theme. For myself and to share it with others.
The first prototype is already live on my blog. There's no testing ground like home.
I've learned a lot on the way. One of the simple things is how to share content on social networks right from your website. Sure, you can embed a Twitter widget. But most of them come with strings attached.
TL: DR - Take me to the code (opens the JSFiddle for this article)
Why bother creating your own button?
Let's take a look a the following example code built by https://publish.twitter.com/#.
<blockquote class="twitter-tweet">
<p lang="en" dir="ltr">
Sunsets don't get much better than this one over
<a href="https://twitter.com/GrandTetonNPS?ref_src=twsrc%5Etfw">
@GrandTetonNPS
</a>.
<a href="https://twitter.com/hashtag/nature?src=hash&ref_src=twsrc%5Etfw">
#nature
</a>
<a href="https://twitter.com/hashtag/sunset?src=hash&ref_src=twsrc%5Etfw">
#sunset
</a>
<a href="http://t.co/YuKy2rcjyU">
pic.twitter.com/YuKy2rcjyU
</a>
</p>
— US Department of the Interior (@Interior)
<a href="https://twitter.com/Interior/status/463440424141459456?ref_src=twsrc%5Etfw">
May 5, 2014
</a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Everything's cool except for the script part.
Almost 100kb for a single share button seems a bit much, especially if you're after a decent lighthouse score.
The good news: There's an official Twitter API to the rescue. Let's see how it works.
Create the markup
Let's use JSFiddle to quickly bootstrap this project. Start by adding the following content:
Button HTML:
Icon by Simpleicons
<button id="button--twitter" class="btn btn--blue">
<i class="btn__icon">
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Twitter</title><path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/></svg>
</i>
<span class=btn__text>
Share to Twitter!
</span>
</button>
Button CSS:
.btn {
cursor: pointer;
border: none;
border-radius: 4px;
padding: 0.25rem 0.5rem;
}
.btn--blue {
background-color: #1DA1F2;
color: #fff;
fill: #fff;
}
.btn__icon * {
display: inline;
height: 1rem;
width: 1rem;
}
.btn__text {
font-size: 1rem;
font-weight: 600;
}
Add a title and text to share
We'll want to have something on our screen to share as well. I'll go into detail about the technique behind it in a second. For now, let's add a h1
title and some text in a p
tag.
Add the following text right above the button markup in your fiddle. You can pick any text you like as well:
<article>
<h1>Create a Twitter Share button</h1>
<p>Don't want to add lots of additional, third party scripts to your app for a simple feature? Then you might be curious about how to build your own "Share to Twitter" button!</p>
<a href="https://blog.q-bit.me/how-to-create-a-share-to-twitter-button-with-html-css-javascript">Read the article</a>
</article>
The result
You'll receive a tiny article that looks like this. Nice and clean.
Create the scripts
Let's see what we have in the markup:
- A heading element that includes our article's title
- A paragraph with some text
- A link that directs us to a different site
- A button we can attach an id of
button--twitter
Great, that's all we need.
Twitter's web intent - API
Did I say there's an API for that? A properly documented one as well. Even the widgets.js
from earlier makes use of it.
In our case, we'll want to point at the following base URL:
Which is documented here: https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/web-intent
Let's build a simple case
- I want my users to be able to share content from a static website
- The tweet should include a title, some text, and a link
- When clicking on the button, the user is directed to their Twitter feed where they can share the content
In technical terms, you'll want to
- Grab the
h1
tag from your site usingdocument.querySelector
- Alternatively: Use the
p
tag's text - Grab the
a
tag and extract itshref
. - Alternatively: Extract the link with
window.location.href
- Use
window.open
to target the - Attach the functionality to the Twitter button
⚠️ Heads up
When using the_blank
link target in JSFiddle, you might end up with anERR_BLOCKED_BY_RESPONSE
error. In this case, we're simply using_top
Next, let's translate it into code. Add the following to your Fiddle's Javascript part:
const twitterUrl = "https://twitter.com/intent/tweet/";
const linkTarget = '_top'
const windowOptions = 'menubar=no,status=no,height=750,width=500'
function extractTitleText() {
return document.querySelector('h1').innerText;
}
function extractAnchorLink() {
return document.querySelector('a').href;
}
function extractWindowLink() {
return window.location.href;
}
function openTwitterWindow(text, link) {
const twitterQuery = `text=${text}&url=${link}`;
return window.open(`${twitterUrl}?${twitterQuery}&`, linkTarget, windowOptions);
}
function registerShareButton() {
const text= extractTitleText()
const link = extractAnchorLink();
const twitterButton = document.querySelector('#button--twitter');
twitterButton.addEventListener('click', () => openTwitterWindow(text, link))
}
registerShareButton()
Save your code and give it a try. The final result should look something like this:
Sharing to other social networks
What if I told you the same was possible with other social networks like:
- Facebook
https://www.facebook.com/sharer.php?u=<url>
- Reddit
https://www.reddit.com/submit?url=<url>&title=<title>
- Linkedin
https://www.linkedin.com/sharing/share-offsite/?url=<url>
With your newly developed skills, implementing these should be cake. So go out there and make sharing simple & lightweight, as it should be.