Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Add Social Share Buttons to Your Static Site Without Tracking


This post is written for Jekyll but everything will work for any site since it's just HTML, CSS and a touch of optional JavaScript.

Quick Jump: Why Not Use a Third Party Service / Widget? | Implementing Your Own Social Share Icons

In this article we’re going to quickly build social share icons that are sticky floated to the side of the page on large devices and disappear on smaller devices – but there’s also smaller social share buttons at the bottom of this page too which aren’t sticky.

You can see them in action on this page. The basic idea is when on smaller devices screen real estate is very tight and it’s often too distracting to have them be sticky anywhere – especially if you have a sticky header already.

By the way, we’re also going to do this in such a way where everything will work without needing to insert JavaScript tracking snippets onto your page for each social platform that you plan to support.

Although it’s worth pointing out if someone clicks and shares your link then that social platform will know about it, but that sure beats having a tracking pixel or JavaScript snippet on the page that tracks every page load even if someone doesn’t share the page or post.

Why Not Use a Third Party Service / Widget?

Regular readers of this blog might notice that the social icons on this site as of a few days ago look different than before. That’s because for ~3 years I was using a third party service called Sumo to provide social icons.

I chose them originally because back then they were a different company. They offered a few kind of neat blog related features like showing heat maps of where people clicked, how far down people were reading in articles and social share icons.

But they removed most of those features and now they are focusing on other things so I questioned on whether or not I should continue using them. It only took about 10 seconds of thinking to decide to drop them because:

  1. uBlock Origin was blocking the icons from appearing
  2. The only feature advantage was it showed the share count for Twitter
  3. Sumo was tracking your information with no benefit to you or me

The first one is a pretty big problem. A lot of developers (myself included) run ad block tools. I’ve had a number of people email me saying I should add social share icons but I had them – they were just hidden, so that’s not good.

The second one isn’t a huge advantage because it didn’t accurately track the share counts in the end and truthfully the main reason I have them in the first place is to make it easier for folks to share an article they like. I don’t really care about displaying the share count.

Another problem was Sumo had a JavaScript snippet that you had to add to each page which caused pages to take longer to load and they tracked it as well. I’m all for minimalism and after factoring in all of the above I decided to roll my own set up.

Switching from Sumo to another social share service would have likely had the same problems so rolling my own widget felt like the right play.

The whole thing took about 30 minutes from end to end. That’s making the decision, wiring up the new icons, adding Jekyll specific features and closing my Sumo account. After following the steps below I bet you’ll be able to get everything up in running in about 5 minutes as long as you’re using Bootstrap and have access to some type of icon library.

Implementing Your Own Social Share Icons

I happen to be using Jekyll but since Jekyll is a static site generator we’re only going to be dealing with HTML, CSS and a bit of optional JavaScript. This strategy will work for any static site generator.

Also, Bootstrap isn’t a hard dependency. I’m only using it to add CSS classes to hide the floating icons on smaller devices so if you’re using something else that’s no problem, you can easily drop in an alternative.

The same can be said for the icons. I’m personally using Font Awesome 4.x but if you’re using something else that will be a quick CSS class change in 3 spots.

Let’s start off with the HTML.

HTML / Liquid

I’m using the Liquid template engine which is what Jekyll uses but I’m sure you’ll have no problem switching things to your template engine of choice, or even straight up HTML if you’re not using a static site generator.

First things first, let’s deal with the floating icons. You’ll want to drop this snippet into your main layout, most likely outside of your main container:

<div class="social-share-floating-bar hidden-sm hidden-xs">
  {% include social-share.html %}

The hidden-sm and hidden-xs classes are Bootstrap 3.x specific and they ensure this div gets hidden on smaller devices. If you’re using Bootstrap 4.x then check out this SO answer.

And then if you want different buttons to always be visible somewhere else such as on the bottom of the page then add this in:

<div class="social-share-btns-container">
  <div class="social-share-btns">
    {% include social-share.html text_label=true %}

I’m taking advantage of Jekyll’s include files which is something I’ve talked about in a previous article. The basic idea is the contents of that include tag will be replaced with a bunch of HTML.

This is what the social-share.html include file looks like:

{% assign title = page.title | default: layout.title %}
{% capture tweet_by %} by @{{ site.author.contact.twitter }}{% endcapture %}
{% assign share_url = site.url | append: page.url | url_encode %}
{% assign tweet_hashtags = "" | split: "," %}

{% if page.tags contains "docker" %}
  {% assign tweet_hashtags = tweet_hashtags | push: "Docker" %}
{% endif %}
{% if page.tags contains "ansible" %}
  {% assign tweet_hashtags = tweet_hashtags | push: "Ansible" %}
{% endif %}
{% if page.tags contains "flask" %}
  {% assign tweet_hashtags = tweet_hashtags | push: "Flask" %}
{% endif %}
{% capture tweet_hashtags_output %}&hashtags={{ tweet_hashtags | array_to_sentence_string: "," | remove: " " }}{% endcapture %}

<a class="{% if include.text_label %}share-btn{% endif %} share-btn-twitter"
    href="https://twitter.com/intent/tweet?url={{ share_url }}&text={{ title | append: tweet_by | url_encode }}{{ tweet_hashtags_output }}">
  <i class="fa fa-twitter"></i>
  {% if include.text_label %}Tweet{% endif %}
<a class="{% if include.text_label %}share-btn{% endif %} share-btn-facebook"
   href="https://www.facebook.com/sharer/sharer.php?u={{ share_url }}&title={{ title | url_encode }}">
  <i class="fa fa-facebook"></i>
  {% if include.text_label %}Share{% endif %}

<a class="{% if include.text_label %}share-btn{% endif %} share-btn-linkedin"
   href="http://www.linkedin.com/shareArticle?mini=true&url={{ share_url }}&title={{ title | url_encode }}">
  <i class="fa fa-linkedin"></i>
  {% if include.text_label %}Share{% endif %}

There’s a decent amount of stuff going on here. In the end this outputs 3 different links. The rest of it is Liquid specific which we’ll go over soon.

Here’s the HTML result of processing that Liquid template:

<a class="share-btn-twitter"
  <i class="fa fa-twitter"></i>

<a class="share-btn-facebook"
  <i class="fa fa-facebook"></i>

<a class="share-btn-linkedin"
  <i class="fa fa-linkedin"></i>

The really important bits are the href attributes in the links. That’s how you’re supposed to format your links for Twitter, Facebook and LinkedIn.

I’m also using Font Awesome 4.x, so if you’re using something else feel free to swap out the classes in the <i> tags to use your icons instead.

If you wanted to add more social buttons you would lookup what URL format they expect and add them to the list. You can also reorder the links however you like.

Now let’s talk a little bit about the Jekyll specifics. I’m going to address each main concept in its own bullet point starting from the top of the include file:

  • Use a page’s title attribute but fall back to using the layout’s title if that’s unavailable
  • Prepare a string so I can output “ by @nickjanetakis” in the Tweet
  • Create an absolute URL as share_url and encode it so things like @ turn into %40
  • Create a tweet_hashtags array (I know, it’s a bit funky in Jekyll)
  • Add specific hashtags depending on what a post is tagged with
  • Prepare a string to store the hashtags in the format we’ll add to the href
  • If include.text_label is present then add the button class
  • Ensure all of the necessary variables in the href attributes are URL encoded
  • If include.text_label is present then display a “Tweet” or “Share” text label

So in the end the include file lets us reuse the same links in 2 different ways. One to show floated icons and another to show buttons. That’s optional of course but if you’re using a static site generator you might as well take advantage of its features to reduce duplication.


With the markup out of the way, let’s style things up:

.social-share-floating-bar {
  position: fixed;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);

.social-share-floating-bar a {
  display: block;
  transition: all 0.3s ease;
  padding: 16px;
  color: #fff;
  font-size: 20px;
  text-align: center;

.social-share-btns-container {
  font-size: 14px;
  text-align: center;

.social-share-btns {
  display: inline-block;

.social-share-btns .share-btn {
  margin: 0 5px;
  padding: 4px 8px;
  color: #fff;

.social-share-btns .share-btn i {
  display: inline-block;
  margin-right: 5px;

.share-btn {
  background-color: #95a5a6;

.share-btn:hover, .share-btn:active, .share-btn:visited {
  background-color: #798d8f;
  text-decoration: none;

.share-btn-twitter {
  background-color: #00aced;

.share-btn-twitter:hover, .share-btn-twitter:active, .share-btn-twitter:visited {
  background-color: #0087ba;

.share-btn-facebook {
  background-color: #3b5998;

.share-btn-facebook:hover, .share-btn-facebook:active, .share-btn-facebook:visited {
  background-color: #2d4373;

.share-btn-linkedin {
  background-color: #007bb6;

.share-btn-linkedin:hover, .share-btn-linkedin:active, .share-btn-linkedin:visited {
  background-color: #005983;

I’m not going to go over the CSS line by line, but this is a pretty bare bones set up to make sure each social site has its own brand specific colors and that the buttons have a decent amount of padding depending on how they are being presented.

I tested everything in IE11, Edge, FireFox and Chrome and it all works out. It may work with older and other browsers too, let me know in the comments!


Technically everything will work fine without JavaScript. If you click one of share links it will load up in a new window. You can try it on this page now if you want to see how it works.

But take note of the Twitter link. Instead of it loading in a separate full size window it gets loaded in a custom sized window instead.

That’s because I have a little Twitter specific snippet added to my page, which is: <script type="text/javascript" async src="https://platform.twitter.com/widgets.js"></script>

That snippet was taken from Twitter’s official docs. Facebook and LinkedIn might have similar snippets but I haven’t bothered to check, but you could also use custom JS to set the window height and width yourself instead of using their snippets if you really wanted to.

Personally I wouldn’t even want to use their specific JS snippets if it existed because then those sites would be tracking each page view. The only reason I do it with Twitter is because I happen to be using their JS snippet for another Twitter related feature on the page (the follow button in the footer).

So that’s it. With just a little bit of markup and CSS you can get social share icons and buttons on your site without too much of a headache. I hope you found this useful!

What are you using for social share buttons on your site? Let me know below.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.