How to add a print button to WordPress

Short answer

The quickest route is a Custom HTML block containing a single anchor tag, which works on any theme with no plugin. For a button on every post, register a shortcode in a child theme or site-specific plugin and append it with the_content filter. WooCommerce order pages need window.print() instead, because they are login-gated.

There are five ways to put a print button on a WordPress site, and they differ mainly in how much of your future they cost. A Custom HTML block takes thirty seconds but has to be pasted into every post. A theme filter takes fifteen minutes and then never needs touching again. Pick by how many posts you have.

The five routes compared.
RouteEffortApplies toSurvives a theme update
A pluginTwo minutesEverything, with settingsYes
Custom HTML blockThirty secondsOne postYes
Synced patternFive minutesEvery post you insert it intoYes
Shortcode plus the_content filterFifteen minutesEvery post automaticallyYes, if it lives in a child theme or a plugin
Editing the parent theme templateTen minutesWhatever the template coversNo. It is wiped on the next update

Route 1: install a plugin

  1. Open the plugin installerIn wp-admin go to Plugins → Add New.
  2. Search and installSearch for a print or print-friendly plugin, click Install Now, then Activate. The PrintxPDF WordPress plugin adds Print, PDF and Email buttons and needs no API key on the free tier.
  3. Choose placementIn the plugin settings pick top, bottom or both, and inline or floating. Bottom-of-article is the safest default: a floating button competes with cookie banners and chat widgets on mobile.
  4. Limit it to the right post typesTurn the button off on the home page, archives and search results. It belongs on single posts, pages and any custom post type that people actually print.
  5. Check the outputOpen a post, click the button and read what comes out. If the plugin only calls the browser print dialog, you still need a print stylesheet, see writing a print stylesheet.

Route 2: a Custom HTML block, no plugin

In the block editor, add a Custom HTML block wherever you want the button and paste this. It is a plain anchor, so it works in every theme, needs no JavaScript to be clickable, and cannot break your site.

<!-- Printer-friendly link. Works with JavaScript disabled. -->
<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,sans-serif;text-decoration:none;border:2px solid currentColor;
  border-radius:6px;color:inherit}
@media print{.pxp-print{display:none !important}}
</style>
Tip

Turn that block into a synced pattern (select the block → the three-dot menu → Create pattern, with "Synced" on). Insert the pattern into other posts and every copy updates when you edit the original. This is the old Reusable Blocks feature under its current name.

Route 3: a shortcode you can drop anywhere

A shortcode gives you [print_button] in any editor, widget or page builder, and one place to change the markup later. Put this in a child theme’s functions.php or, better, in a small site-specific plugin so it survives a theme change too.

<?php
// wp-content/plugins/site-print-button/site-print-button.php

function pxp_print_button( $atts ) {
    $a = shortcode_atts( array( 'label' => 'Print / PDF' ), $atts, 'print_button' );

    $target = 'https://printxpdf.com/print?url=' . rawurlencode( get_permalink() );

    return sprintf(
        '<a class="pxp-print" href="%s" target="_blank" rel="noopener">%s</a>',
        esc_url( $target ),
        esc_html( $a['label'] )
    );
}
add_shortcode( 'print_button', 'pxp_print_button' );

Use it as [print_button] or [print_button label="Print this recipe"]. Three details matter: shortcode_atts gives you a default label, rawurlencode keeps query strings and non-ASCII characters in the permalink intact, and esc_url plus esc_html are not optional, a shortcode that echoes unescaped attributes is a cross-site scripting hole.

Route 4: put it on every post automatically

Rather than editing templates, append the shortcode with a filter. The three guards below matter: without them the button also appears in excerpts, RSS feeds, related-post widgets and anywhere else the theme runs the loop.

add_filter( 'the_content', function ( $content ) {
    if ( ! is_singular( array( 'post', 'page' ) ) ) {
        return $content;   // not a single view
    }
    if ( ! in_the_loop() || ! is_main_query() ) {
        return $content;   // a widget or a related-posts loop
    }

    return $content . do_shortcode( '[print_button]' );
} );
Watch out

Never edit the parent theme’s functions.php or its single.php. The next theme update overwrites both and your button disappears with no error message. Use a child theme, or a two-file plugin in wp-content/plugins/, which also survives switching themes entirely.

Block themes and the Site Editor

On a block theme, the template route lives in Appearance → Editor → Templates → Single. Add a Shortcode block or a Custom HTML block into the template near the post content, then save. It applies to every post using that template and it is stored in the database rather than in theme files, so it survives updates.

Testing what your theme actually produces on paper? Convert the page to PDF and read it.

HTML to PDF

WooCommerce is a different problem

Order confirmations, invoices and packing slips are the pages customers most want to print, and they are the ones a URL-based cleaner cannot help with, because they sit behind a login and an order key. A tool fetching that URL gets the login screen.

  • On order and account pages, use window.print() and a real print stylesheet. That prints what the logged-in browser can already see.
  • Hook the button onto woocommerce_order_details_after_order_table for the thank-you and order-detail views.
  • For the product page, woocommerce_single_product_summary at priority 35 puts it under the add-to-cart area.
  • For proper invoices and packing slips, use a dedicated invoicing plugin. It generates a real PDF server-side with your tax details on it, which is what accountants and customs forms need.
  • Hide the button, the cart widget, the menu and the upsell blocks in @media print or the invoice arrives with a "You may also like" carousel on it.
add_action( 'woocommerce_order_details_after_order_table', function () {
    printf(
        '<button type="button" class="pxp-print button" onclick="window.print()">%s</button>',
        esc_html__( 'Print this order', 'my-theme' )
    );
} );

Which one should you pick

If you have fewer than twenty posts, use the Custom HTML block and stop reading. If you publish regularly, spend the fifteen minutes on the shortcode and the filter: it is roughly thirty lines of code, it lives outside the theme, and it means every post you write from now on has the button without you thinking about it. If you would rather not touch PHP at all, a plugin is a perfectly respectable answer.

Whichever route you take, the button is only half the job. A button that opens a print dialog full of navigation and sidebars is worse than no button, because now the reader blames you rather than the browser. Pair it with a print stylesheet, and run the printer-friendly checklist once across your main templates. If you are not on WordPress, the same anchor works everywhere, see adding a print button to any website or generate one on the button builder.

Printing something readers will act on? Put a QR code on the paper that leads back to the live page.

QR Code Generator

Frequently asked questions

What is the easiest way to add a print button in WordPress?

A Custom HTML block containing a single anchor tag. It takes thirty seconds, needs no plugin and no PHP, and works in every theme. The only drawback is that you have to paste it into each post, which a synced pattern solves.

How do I add a print button to every post at once?

Register a shortcode in a child theme or site-specific plugin, then append it with a the_content filter guarded by is_singular, in_the_loop and is_main_query. Those guards stop the button appearing in excerpts, feeds and related-post widgets.

Can I add a print button without a plugin?

Yes. A print button is one anchor tag or one button element calling window.print(). Neither needs a plugin. Plugins are worth it when you want placement settings, analytics or a cleaned-up output page without writing CSS.

Why does my WooCommerce order print with the whole shop menu on it?

Because the order page has no print stylesheet. Add a @media print block that hides the header, navigation, cart widget, footer and the print button itself, and reset the order table to full width.

Should the print button call window.print() or open a cleaner?

Call window.print() when you have written a good print stylesheet and the page is login-gated. Send the URL to a cleaner when the page is public and you have not written print CSS, because the cleaner does the layout work for you.