Navigation & Accessibility

Free Print Button Widget

Give visitors a one-click way to print your page.

A clean inline button that opens the browser print dialog with a single click. It is ideal for recipe sites, invoices, articles, and any page visitors may want on paper. Install it with one script tag wherever you want the button to appear.

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/print-button.js" data-hl-label="Print this page" async></script>
<!-- Free Print Button widget by haynes lab — https://hayneslab.dev/tools/widgets/print-button -->
Inline (self-contained)html
<!-- Free Print Button widget by haynes lab — https://hayneslab.dev/tools/widgets/print-button -->
<script data-hl-label="Print this page">
/*!
 * haynes lab — Print Button widget (free)
 * Docs & embed code: https://hayneslab.dev/tools/widgets/print-button
 */
(function () {
  'use strict';

  var PREFIX = 'hlw-print-button';
  var STYLE_ID = 'hlw-print-button-styles';

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

  function injectStyles() {
    if (document.getElementById(STYLE_ID)) return;
    var css =
      '.' + PREFIX + ', .' + PREFIX + ' * { box-sizing: border-box; }' +
      '.' + PREFIX + ' { display: inline-flex; align-items: center; gap: 10px;' +
      ' font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }' +
      '.' + PREFIX + '__btn { display: inline-flex; align-items: center; gap: 8px;' +
      ' padding: 9px 18px; font: inherit; font-size: 14px; font-weight: 600; line-height: 1.4;' +
      ' color: #1f2937; background: #ffffff; border: 1px solid #d1d5db; border-radius: 8px;' +
      ' cursor: pointer; transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease; }' +
      '.' + PREFIX + '__btn:hover { color: var(--hlw-accent); border-color: var(--hlw-accent); }' +
      '.' + PREFIX + '__btn:active { background: #f9fafb; }' +
      '.' + PREFIX + '__btn:focus-visible { outline: 2px solid var(--hlw-accent); outline-offset: 2px; }' +
      '.' + PREFIX + '__icon { display: inline-flex; flex: 0 0 auto; }' +
      '.' + PREFIX + '__icon svg { display: block; }' +
      '.' + PREFIX + '__credit { font-size: 11px; display: inline-flex; align-items: center;' +
      ' gap: 4px; color: #9ca3af; text-decoration: none; }' +
      '.' + PREFIX + '__credit svg { display: block; }' +
      '.' + PREFIX + '__credit:hover { color: #6b7280; text-decoration: underline; }' +
      '@media print { .' + 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 printerSvg() {
    var svgNS = 'http://www.w3.org/2000/svg';
    var svg = document.createElementNS(svgNS, 'svg');
    svg.setAttribute('viewBox', '0 0 24 24');
    svg.setAttribute('width', '16');
    svg.setAttribute('height', '16');
    svg.setAttribute('fill', 'none');
    svg.setAttribute('stroke', 'currentColor');
    svg.setAttribute('stroke-width', '2');
    svg.setAttribute('stroke-linecap', 'round');
    svg.setAttribute('stroke-linejoin', 'round');
    svg.setAttribute('aria-hidden', 'true');
    svg.setAttribute('focusable', 'false');
    var paths = [
      'M6 9V2h12v7',
      'M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2',
      'M6 14h12v8H6z'
    ];
    paths.forEach(function (d) {
      var p = document.createElementNS(svgNS, 'path');
      p.setAttribute('d', d);
      svg.appendChild(p);
    });
    return svg;
  }

  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 build(script) {
    var label = script.getAttribute('data-hl-label') || 'Print';
    var showIcon = script.getAttribute('data-hl-icon') !== 'false';
    var accent = script.getAttribute('data-hl-accent') || '#f97316';

    injectStyles();

    var root = el('span', PREFIX);
    root.style.setProperty('--hlw-accent', accent);

    var btn = el('button', PREFIX + '__btn');
    btn.type = 'button';
    btn.setAttribute('aria-label', label);
    if (showIcon) {
      var icon = el('span', PREFIX + '__icon');
      icon.appendChild(printerSvg());
      btn.appendChild(icon);
    }
    btn.appendChild(document.createTextNode(label));
    btn.addEventListener('click', function () {
      try {
        window.print();
      } catch (e) {
        console.warn('[haynes lab print-button] window.print() is not available.', e);
      }
    });
    root.appendChild(btn);

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

    if (script.parentNode && script.parentNode.nodeName !== 'HEAD') {
      script.insertAdjacentElement('afterend', root);
    } else {
      document.body.appendChild(root);
    }
  }

  function init() {
    var script = findScript();
    if (!script) {
      console.warn('[haynes lab print-button] 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-label"Print"The text shown on the button.
data-hl-icon"true"Set to "false" to hide the printer icon and show text only.
data-hl-accent"#f97316"Color of the hover state and focus outline.

Frequently asked questions

How do I install the Print Button?

Paste the script tag exactly where you want the button to appear in your page content — the button renders inline right at that spot. Clicking it opens the visitor's browser print dialog via window.print().

Can I change the label, icon, and colors?

Yes — set data-hl-label for custom button text, data-hl-icon="false" to hide the printer icon, and data-hl-accent to change the hover and focus color to match your brand.

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