Navigation & Accessibility

Free Side Share Bar Widget

A slim vertical share strip pinned to the edge of every page.

A fixed vertical bar that floats mid-screen on the left or right edge of the viewport with share buttons for X, Facebook, LinkedIn, email, and copy-link. It is ideal for blogs and content sites that want sharing always within reach without interrupting the reading flow. Install it with a single script tag anywhere on your site.

Live demo

Embed this widget

Paste either snippet into your page — a Custom HTML block on WordPress, Shopify, or Squarespace works too. Both snippets update live as you customize, so what you copy is exactly what you configured.

Hosted (recommended)html
<script src="https://hayneslab.dev/widgets/side-share-bar.js" data-hl-position="right" data-hl-url="https://hayneslab.dev" data-hl-title="Free website widgets from haynes lab" async></script>
<!-- Free Side Share Bar widget by haynes lab — https://hayneslab.dev/tools/widgets/side-share-bar -->
Inline (self-contained)html
<!-- Free Side Share Bar widget by haynes lab — https://hayneslab.dev/tools/widgets/side-share-bar -->
<script data-hl-position="right" data-hl-url="https://hayneslab.dev" data-hl-title="Free website widgets from haynes lab">
/*!
 * haynes lab — Side Share Bar widget (free)
 * Docs & embed code: https://hayneslab.dev/tools/widgets/side-share-bar
 */
(function () {
  'use strict';

  var PREFIX = 'hlw-side-share-bar';
  var STYLE_ID = 'hlw-side-share-bar-styles';

  function findScript() {
    return document.currentScript ||
      document.querySelector('script[src*="widgets/side-share-bar.js"]');
  }

  function injectStyles() {
    if (document.getElementById(STYLE_ID)) return;
    var css =
      '.' + PREFIX + ', .' + PREFIX + ' * { box-sizing: border-box; }' +
      '.' + PREFIX + ' { position: fixed; top: 50%; transform: translateY(-50%); z-index: 99990;' +
      ' display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 6px 4px;' +
      ' font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;' +
      ' background: #ffffff; border: 1px solid #e5e7eb; box-shadow: 0 2px 10px rgba(0,0,0,0.08); }' +
      '.' + PREFIX + '--left { left: 0; border-left: 0; border-radius: 0 12px 12px 0; }' +
      '.' + PREFIX + '--right { right: 0; border-right: 0; border-radius: 12px 0 0 12px; }' +
      '.' + PREFIX + '--stage { position: absolute; z-index: 10; }' +
      '.' + PREFIX + '__btn { width: 38px; height: 38px; display: flex; align-items: center;' +
      ' justify-content: center; padding: 0; margin: 0; border: 0; border-radius: 8px;' +
      ' background: transparent; color: #4b5563; cursor: pointer; text-decoration: none; }' +
      '.' + PREFIX + '__btn:hover { color: var(--hlw-accent); background: #f9fafb; }' +
      '.' + PREFIX + '__btn:focus-visible { outline: 2px solid var(--hlw-accent); outline-offset: 1px; }' +
      '.' + PREFIX + '__btn svg { width: 18px; height: 18px; fill: currentColor; display: block; }' +
      '.' + PREFIX + '__toast { position: absolute; top: 50%; transform: translateY(-50%);' +
      ' padding: 4px 10px; border-radius: 6px; background: #111827; color: #ffffff;' +
      ' font-size: 12px; line-height: 1.4; white-space: nowrap; pointer-events: none;' +
      ' opacity: 0; transition: opacity 0.2s ease; }' +
      '.' + PREFIX + '--left .' + PREFIX + '__toast { left: calc(100% + 8px); }' +
      '.' + PREFIX + '--right .' + PREFIX + '__toast { right: calc(100% + 8px); }' +
      '.' + PREFIX + '__toast--show { opacity: 1; }' +
      '.' + PREFIX + '__credit { writing-mode: vertical-rl; margin-top: 4px; padding-top: 5px;' +
      ' border-top: 1px solid #f3f4f6; font-size: 11px; line-height: 1; color: #9ca3af;' +
      ' text-decoration: none; }' +
      '.' + PREFIX + '__credit svg { display: block; margin: 0 auto 3px; }' +
      '.' + PREFIX + '__credit:hover { color: #6b7280; text-decoration: underline; }' +
      '@media (max-width: 600px) { .' + PREFIX + ' { display: none; } }';
    var style = document.createElement('style');
    style.id = STYLE_ID;
    style.textContent = css;
    document.head.appendChild(style);
  }

  function el(tag, className, text) {
    var node = document.createElement(tag);
    if (className) node.className = className;
    if (text != null) node.textContent = text;
    return node;
  }

  function logoSvg() {
    var svgNS = 'http://www.w3.org/2000/svg';
    var svg = document.createElementNS(svgNS, 'svg');
    svg.setAttribute('viewBox', '0 0 32 32');
    svg.setAttribute('width', '13');
    svg.setAttribute('height', '13');
    svg.setAttribute('aria-hidden', 'true');
    svg.setAttribute('focusable', 'false');
    function circle(cx, cy, r, attrs) {
      var c = document.createElementNS(svgNS, 'circle');
      c.setAttribute('cx', cx);
      c.setAttribute('cy', cy);
      c.setAttribute('r', r);
      for (var key in attrs) c.setAttribute(key, attrs[key]);
      svg.appendChild(c);
    }
    circle(16, 16, 16, { fill: '#0f0a0a' });
    circle(16, 16, 12, { fill: 'none', stroke: '#fff5f5', 'stroke-width': 1, opacity: 0.3 });
    circle(16, 16, 9, { fill: 'none', stroke: '#fff5f5', 'stroke-width': 1, opacity: 0.5 });
    circle(16, 16, 6, { fill: 'none', stroke: '#fff5f5', 'stroke-width': 1.2, opacity: 0.9 });
    circle(16, 16, 3, { fill: '#06b6d4' });
    circle(24.5, 7.5, 2, { fill: '#f97316' });
    circle(7, 16, 1.8, { fill: '#f97316' });
    circle(20, 20, 1.5, { fill: '#f97316' });
    return svg;
  }

  function iconSvg(pathD) {
    var svgNS = 'http://www.w3.org/2000/svg';
    var svg = document.createElementNS(svgNS, 'svg');
    svg.setAttribute('viewBox', '0 0 24 24');
    svg.setAttribute('aria-hidden', 'true');
    svg.setAttribute('focusable', 'false');
    var path = document.createElementNS(svgNS, 'path');
    path.setAttribute('d', pathD);
    svg.appendChild(path);
    return svg;
  }

  var ICONS = {
    x: 'M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z',
    facebook: 'M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z',
    linkedin: 'M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z',
    email: 'M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0l-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z',
    copy: 'M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z'
  };

  function build(script) {
    var position = (script.getAttribute('data-hl-position') || 'left').toLowerCase();
    if (position !== 'right') position = 'left';
    var accent = script.getAttribute('data-hl-accent') || '#f97316';
    var url = script.getAttribute('data-hl-url') || window.location.href;
    var title = script.getAttribute('data-hl-title') || document.title || url;

    var raw = script.getAttribute('data-hl-networks') || 'x,facebook,linkedin,email,copy';
    var networks = raw.toLowerCase().split(',').map(function (n) {
      return n.replace(/^\s+|\s+$/g, '');
    }).filter(function (n) { return ICONS[n]; });
    if (!networks.length) {
      console.warn('[haynes lab side-share-bar] data-hl-networks has no valid networks (x, facebook, linkedin, email, copy). Nothing rendered.');
      return;
    }

    var stage = script.closest && script.closest('.widget-demo__stage');

    injectStyles();

    var root = el('div', PREFIX + ' ' + PREFIX + '--' + position + (stage ? ' ' + PREFIX + '--stage' : ''));
    root.setAttribute('role', 'region');
    root.setAttribute('aria-label', 'Share this page');
    root.style.setProperty('--hlw-accent', accent);

    var encUrl = encodeURIComponent(url);
    var encTitle = encodeURIComponent(title);
    var targets = {
      x: 'https://twitter.com/intent/tweet?url=' + encUrl + '&text=' + encTitle,
      facebook: 'https://www.facebook.com/sharer/sharer.php?u=' + encUrl,
      linkedin: 'https://www.linkedin.com/sharing/share-offsite/?url=' + encUrl,
      email: 'mailto:?subject=' + encTitle + '&body=' + encodeURIComponent(title + '\n\n' + url)
    };
    var labels = {
      x: 'Share on X',
      facebook: 'Share on Facebook',
      linkedin: 'Share on LinkedIn',
      email: 'Share by email',
      copy: 'Copy link'
    };

    var toast = el('span', PREFIX + '__toast', 'Link copied!');
    toast.setAttribute('role', 'status');
    var toastTimer = null;

    networks.forEach(function (name) {
      var item;
      if (name === 'copy') {
        item = el('button', PREFIX + '__btn');
        item.type = 'button';
        item.setAttribute('aria-label', labels.copy);
        item.title = labels.copy;
        item.addEventListener('click', function () {
          function done() {
            toast.classList.add(PREFIX + '__toast--show');
            if (toastTimer) clearTimeout(toastTimer);
            toastTimer = setTimeout(function () {
              toast.classList.remove(PREFIX + '__toast--show');
            }, 1600);
          }
          if (navigator.clipboard && navigator.clipboard.writeText) {
            navigator.clipboard.writeText(url).then(done, done);
          } else {
            var tmp = document.createElement('textarea');
            tmp.value = url;
            tmp.style.position = 'fixed';
            tmp.style.opacity = '0';
            document.body.appendChild(tmp);
            tmp.select();
            try { document.execCommand('copy'); } catch (e) { /* best effort */ }
            document.body.removeChild(tmp);
            done();
          }
        });
      } else {
        item = el('a', PREFIX + '__btn');
        item.href = targets[name];
        item.setAttribute('aria-label', labels[name]);
        item.title = labels[name];
        if (name === 'email') {
          item.rel = 'noopener';
        } else {
          item.addEventListener('click', function (e) {
            e.preventDefault();
            window.open(targets[name], 'hlw-share', 'width=600,height=540,noopener');
          });
        }
      }
      item.appendChild(iconSvg(ICONS[name]));
      root.appendChild(item);
    });

    var credit = el('a', PREFIX + '__credit');
    credit.appendChild(logoSvg());
    credit.appendChild(document.createTextNode('Powered by haynes lab'));
    credit.href = 'https://hayneslab.dev/tools/widgets/side-share-bar';
    credit.target = '_blank';
    credit.rel = 'noopener';
    root.appendChild(credit);

    root.appendChild(toast);

    if (stage) {
      stage.appendChild(root);
    } else {
      document.body.appendChild(root);
    }
  }

  function init() {
    var script = findScript();
    if (!script) {
      console.warn('[haynes lab side-share-bar] Could not locate its own script tag. Nothing rendered.');
      return;
    }
    build(script);
  }

  if (document.body) {
    init();
  } else {
    document.addEventListener('DOMContentLoaded', init);
  }
})();

</script>

Configuration

Every option is an attribute on the script tag — the same attributes the customizer above exposes. All attributes are optional unless marked required — defaults apply when omitted.

AttributeDefaultDescription
data-hl-position"left"Which edge of the viewport the bar hugs: "left" or "right".
data-hl-networks"x,facebook,linkedin,email,copy"Comma-separated list of buttons to show, in order (x, facebook, linkedin, email, copy).
data-hl-url(none)The URL shared by the buttons; defaults to the current page URL.
data-hl-title(none)The text used in share posts and the email subject; defaults to the page title.
data-hl-accent"#f97316"Hover color for the buttons and focus outlines.

Frequently asked questions

How do I install the Side Share Bar?

Paste the script tag anywhere before the closing </body> tag on your site. The bar renders fixed to the left edge of the viewport, vertically centered, and shares whatever page the visitor is on.

Can I change which side it sits on and which buttons show?

Yes — set data-hl-position="right" to move it to the right edge, and use data-hl-networks to pick and order buttons (e.g. data-hl-networks="x,linkedin,copy"). data-hl-url and data-hl-title override what gets shared, and data-hl-accent sets the hover color.

Does it work on WordPress, Shopify, or Squarespace?

Yes — it is a single vanilla JavaScript file with no dependencies. Paste the snippet into any platform that lets you add custom scripts or edit your theme, including WordPress, Shopify, Squarespace, Wix, and plain HTML sites.

More free widgets

Need a custom widget?

We build custom widgets, integrations, and whole products. Tell us what your site needs and we'll scope it.

Get in Touch