Building a 'Share this page' feature with Hugo

Posted on

It’s easy enough to just copy and paste the JavaScript ‘share this page’ widgets from Facebook, Twitter, LinkedIn etc, but these load their own JavaScript which comes with a performance and they also add their own tracking scripts to your site. They also have different styling and sizes which can give a messy, cluttered look to the page.

Instead, you can build-your-own ‘share this page’ widget with support for Twitter, LinkedIn, Facebook, Email - and the native Web Share API for a neat, privacy-focused and performant solution with a consistent look.

Add the following code block as a partial to your project as something like layouts/partials/share-this-page.html. This uses Bootstrap 5 classes but it can be easily modified to suit your site’s CSS. I’ve used Font Awesome SVG brand icons as partials so that they are inlined, but you could replace them with <img> tags instead.

<div class="share">
  <div>
    <a href="https://twitter.com/intent/tweet?via={{ .Site.Params.twitterID -}}&text={{ .Title }}&url={{ .Permalink }}"
      data-bs-toggle="tooltip" data-bs-placement="top" title="Share on T​witter"
      onclick="window.open(this.href, 'window', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0'); return false;">
      {{- partial "icons/fa/brands/twitter-square.svg" (dict "width" "28" "height" "28") -}}
      <span class="visually-hidden">T​witter</span></a>
  </div>
  <div>
    <a href="https://www.linkedin.com/shareArticle?mini=true&url={{ .Permalink }}&title={{ .Title }}&summary={{ .Summary }}"
      data-bs-toggle="tooltip" title="Share on Link​edIn"
      onclick="window.open(this.href, 'window', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0'); return false;">
      {{- partial "icons/fa/brands/linkedin.svg" (dict "class" "width" "28" "height" "28") -}}
      <span class="visually-hidden">Link​edIn</span></a>
  </div>
  <div>
    <a href="https://www.facebook.com/sharer.php?u={{ .Permalink }}" data-bs-toggle="tooltip"
      title="Share on Facebook"
      onclick="window.open(this.href, 'window', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0'); return false;">
      {{- partial "icons/fa/brands/facebook-square.svg" (dict "width" "28" "height" "28") -}}
      <span class="visually-hidden">Facebook</span></a>
    </div>
  <div>
    <a href="mailto:?subject={{ .Title }}&body=Check out this site {{ .Permalink }}"
       onclick="window.open(this.href, 'window', 'left=20,top=20,width=500,height=500,toolbar=1,resizable=0'); return false;"
      data-bs-toggle="tooltip" title="Share via Email">
      {{- partial "icons/fa/solid/envelope-square.svg" (dict "width" "28" "height" "28") -}}
      <span class="visually-hidden">Email</span></a>
  </div>
  <div>
    <button class="border-0 bg-transparent btn-share-web-api d-none p-0" data-bs-toggle="tooltip" title="Share">
      {{- partial "icons/fa/solid/share-alt-square.svg" (dict "width" "28" "height" "28") -}}
      <span class="visually-hidden">Share</span></button>
  </div>
</div>

I’d suggest loading the Web Share API JavaScript as type="module" so older browsers (which don’t support the Web Share API) will completely ignore it.

<script type="module">
  const shareButton = document.querySelector('.btn-share-web-api');
  // if Web Share API is supported then the button will show by removing Bootstrap's 'd-none' utility class
  if (navigator.share) {
     shareButton.classList.remove('d-none');
  };
  shareButton.addEventListener('click', event => {
    if (navigator.share) {
      navigator.share({
        title: '{{ .Title }} | {{ .Site.Title }}',
        text: '{{ .Description }}',
        url: '{{ .Permalink }}'
      }).then(() => {
        console.log('Thanks for sharing!');
      })
        .catch(console.error);
    }
  });
</script>

You might also like

Migrating an RSS feed from Jekyll to Hugo

Changing the feed template and config for followers of your feed

Bootstrap 5 Print Stylesheet

Optimized CSS for printing

Monetizing your Content with Coil

Setting up the Web Monetization API