How to add a print or PDF button to any website

Updated 2026-08-11 · 8 min read

Short answer: Paste a single anchor tag that opens the current URL in a printer-friendly view, or a button element calling window.print(). Both are a few lines of plain HTML and work in any CMS or static site. Hide the button in @media print, and use the anchor form inside Wix, where embeds are iframes.

A print button is one HTML element. Every plugin, widget and paid service on this subject is packaging around that element. Below are the two versions worth using, when each applies, and where to paste them in the platforms that make it awkward.

Decide what the button should do first

BehaviourWhat it needs from youBest for
window.print() on the current pageA print stylesheet you have written and testedLogin-gated pages: orders, accounts, dashboards, invoices
Open the URL in a printer-friendly viewNothing. The cleaner does the layout workPublic pages, especially when you have no print CSS yet
Both, side by sideA stylesheet, plus one extra linkPublishers who want a paper option and a PDF option

Two behaviours, two different requirements.

If you have not written print CSS, the second option is strictly better today and you can add the first later. If your page is behind a login, the second option cannot work at all: a cleaner fetching that URL gets the sign-in screen, not the order.

Version 1: the plain anchor

No framework, no build step, no dependency. It degrades gracefully: with JavaScript disabled it still opens the cleaner, just without the current URL prefilled.

<!-- Printer-friendly link. Paste anywhere HTML is allowed. -->
<a class="pxp-print"
   href="https://printxpdf.com/print?url="
   onclick="this.href='https://printxpdf.com/print?url='+encodeURIComponent(location.href)"
   target="_blank" rel="noopener">&#9113; Print / PDF</a>

<style>
.pxp-print{display:inline-flex;align-items:center;gap:.5rem;padding:10px 18px;
  font:700 14px/1 system-ui,-apple-system,sans-serif;letter-spacing:.03em;
  text-decoration:none;color:inherit;border:2px solid currentColor;border-radius:6px}
.pxp-print:hover{background:currentColor;color:#fff}
@media print{.pxp-print{display:none !important}}
</style>

encodeURIComponent is the part people leave out, and it is why buttons break on pages with query strings or accented characters in the path. The @media print rule at the bottom is the part everyone leaves out, and it is why printed pages have a "Print" button printed on them.

Version 2: window.print(), CSP-safe

If your site sends a strict Content-Security-Policy header, an inline onclick will be blocked and the button will silently do nothing. Attach a listener instead. Use a real <button type="button">, not an anchor with a javascript: href: buttons are keyboard-operable and announced correctly by screen readers, and type="button" stops it submitting a surrounding form.

<button type="button" class="pxp-print" data-print-page>
  &#9113; Print this page
</button>

<script>
  document.querySelectorAll('[data-print-page]').forEach(function (btn) {
    btn.addEventListener('click', function () {
      window.print();
    });
  });

  // Optional: expand collapsed sections before the dialog paints
  window.addEventListener('beforeprint', function () {
    document.querySelectorAll('details').forEach(function (d) { d.open = true; });
  });
</script>

To open the cleaner from a button instead of an anchor, swap the click handler for window.open('https://printxpdf.com/print?url=' + encodeURIComponent(location.href), '_blank', 'noopener').

Tip: Do not ship an icon on its own. A printer glyph with no label is unrecognisable to a good number of readers under thirty, who have never used one. Label it "Print / PDF", and if you must go icon-only, add an aria-label.

Where to paste it, platform by platform

PlatformWhere it goesGotcha
Static site (Hugo, Jekyll, Eleventy, Astro)The post layout partial, next to the title or after the contentNone. Put it in the layout once and every page has it
SquarespaceA Code Block where you want the buttonSite-wide code injection needs a Business plan or higher; a per-page Code Block does not
WixAdd → Embed Code → Embed HTMLThe embed is an iframe, so window.print() prints only the empty embed. Use the anchor version
WebflowAn Embed element in the DesignerEmbeds render inline, not in an iframe, so both versions work
Shopifysections/main-article.liquid or main-page.liquidUse Liquid to build the URL: {{ canonical_url | url_encode }}
GhostThe post template, or a Code Injection blockHandlebars gives you the absolute URL: {{url absolute="true"}}
Email templatesThe anchor version onlyNo JavaScript runs in email. Hard-code the article URL into the href
Notion, Substack, MediumNot possibleNo custom HTML. Link to the cleaner with the URL written out in full

The Wix case is worth spelling out because it wastes a lot of afternoons. Wix HTML embeds run inside an iframe on a different origin. Calling window.print() there prints the iframe, which contains nothing but your button, and parent.print() is blocked by the same-origin policy. The anchor, which simply navigates a new tab, is unaffected.

Putting it in place

  1. Pick the behaviour Cleaner link for public pages with no print CSS. window.print() for login-gated pages, or for public pages where you have already written and tested a stylesheet.
  2. Paste it into the template, not the page One edit in a layout beats fifty edits in fifty posts. On a hosted CMS, use a synced pattern, a reusable block or a saved section so there is still one source of truth.
  3. Place it where the decision happens Near the title for recipes, tickets and receipts. At the end as well for long articles, which is where a reader decides the piece is worth keeping.
  4. Hide it on paper Add @media print { .pxp-print { display: none !important } }. Do this now, because you will not notice it until a reader mentions it.
  5. Check the keyboard and the screen reader Tab to it, press Enter, and confirm it announces as a link or a button with a real name. type="button" on buttons, rel="noopener" on anchors with target="_blank".
  6. Print the result and read it Do not ship on the strength of the preview thumbnail. Print one page, or save it as a PDF and read it at full size.

Check what your page really produces on paper before you put a button on it.

Generate one instead of writing it

If you would rather pick a colour, size and label than edit CSS, the button builder produces the same markup with inline styles, ready to paste into any CMS. On WordPress specifically, the plugin, block and shortcode routes cover the options in more detail, and the WordPress plugin page has the one-click version.

Add a QR code so the printed sheet still leads back to the live page.

A button without a stylesheet is only half a feature. When you have the button in place, spend an afternoon on a print stylesheet and run the printer-friendly checklist over your main templates.

Frequently asked questions

What is the HTML code for a print button?

The minimum is <button type="button" onclick="window.print()">Print</button>. Use type="button" so it never submits a surrounding form, and add a @media print rule hiding the button, or it prints on the page itself.

Should I use a link or a button for printing?

A button element when it triggers window.print(), because it performs an action on the current page. An anchor when it navigates somewhere, such as opening the page in a printer-friendly view in a new tab. Do not use an anchor with a javascript: href.

Why does my print button not work on Wix?

Wix HTML embeds run inside an iframe, so window.print() prints the empty embed rather than the page, and parent.print() is blocked cross-origin. Use the anchor version, which opens the page URL in a new tab instead.

How do I pass the current page URL to a print tool?

Append it as an encoded query parameter: encodeURIComponent(location.href) in JavaScript, or the url_encode filter in Shopify Liquid. Encoding matters because raw query strings and accented characters break the link.

Does a print button need JavaScript?

Not if it is an anchor pointing at a printer-friendly view, which works with scripting disabled. It does if it calls window.print(). The anchor version is also the only one that works inside an email template.

Tools

Keep reading