A WordPress back button is handy on product, search result and detail pages: one click takes the visitor to the page they came from, like the browser’s own Back button.
The usual <button onclick="history.back()"> does nothing when there is no previous page, for example when the visitor opened the link in a new tab, and it can send people back to Google. This shortcode prints a normal link instead. With JavaScript it goes back one step, but only when the previous page is on your site; otherwise it opens a fallback URL you choose.
[dpc_back_button]goes back, or to the home page[dpc_back_button label="Back to the shop" fallback="/shop/" class="wp-element-button"]
The snippet
<?php
/**
* [dpc_back_button label="Go back" fallback="/shop/" class="my-button"]
* A link that works like the browser's Back button. When there is no previous
* page on this site (direct visit, new tab, link from Google) it opens the fallback URL.
*/
add_shortcode( 'dpc_back_button', 'dpc_back_button_shortcode' );
function dpc_back_button_shortcode( $atts ): string {
$atts = shortcode_atts(
array(
'label' => __( 'Go back', 'dpc' ),
'fallback' => home_url( '/' ),
'class' => '',
),
$atts,
'dpc_back_button'
);
// esc_url() returns '' for javascript: and other unsafe URLs; use the home page then.
$fallback = esc_url( $atts['fallback'] );
if ( '' === $fallback ) {
$fallback = esc_url( home_url( '/' ) );
}
$classes = array( 'dpc-back-button' );
foreach ( preg_split( '/\s+/', (string) $atts['class'], -1, PREG_SPLIT_NO_EMPTY ) as $class ) {
$classes[] = sanitize_html_class( $class );
}
dpc_back_button_script();
return sprintf(
'<a class="%1$s" href="%2$s" data-dpc-back>%3$s</a>',
esc_attr( implode( ' ', array_filter( $classes ) ) ),
$fallback,
esc_html( $atts['label'] )
);
}
/** One small footer script per page, and only on pages that show the button. */
function dpc_back_button_script(): void {
if ( wp_script_is( 'dpc-back-button', 'enqueued' ) ) {
return;
}
$js = <<<'JS'
document.addEventListener('click', function (event) {
var link = event.target.closest('[data-dpc-back]');
// Let Ctrl/Cmd/Shift/middle clicks open the fallback link in a new tab as usual.
if (!link || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
return;
}
var sameSite = false;
try {
sameSite = document.referrer !== '' && new URL(document.referrer).origin === window.location.origin;
} catch (e) {
sameSite = false;
}
// Only go back when the visitor came from a page on this site.
if (sameSite && window.history.length > 1) {
event.preventDefault();
window.history.back();
}
});
JS;
wp_register_script( 'dpc-back-button', false, array(), null, array( 'in_footer' => true ) );
wp_add_inline_script( 'dpc-back-button', $js );
wp_enqueue_script( 'dpc-back-button' );
}
Add it with Scripts Organizer
In Scripts Organizer go to Code Blocks → Add New and give the block a name. Set Trigger location to Everywhere, tick PHP under Script location, paste the code into the PHP editor and publish. Leave Action/Hook empty.
This is a normal add_shortcode() rather than a block with the Shortcode script location on purpose: a Shortcode-location block cannot read attributes, and here every button needs its own label and fallback URL. It also means [dpc_back_button] works the same in the block editor’s Shortcode block, Bricks, Elementor or a classic widget, and the code runs unchanged in a small plugin or an mu-plugin.
How it works
- The shortcode returns an
<a>whosehrefis the fallback URL. Without JavaScript, or when the visitor Ctrl/Cmd-clicks or middle-clicks it, it behaves like any other link. - One click listener on the document handles every back button on the page. It calls
history.back()only whendocument.referrerhas the same origin as the current page and the tab has history. Visitors who came from a search engine or another site get the fallback link instead. esc_url()removesjavascript:and other unsafe URLs; the snippet then uses the home page. The label is escaped and the extra classes go throughsanitize_html_class().- The script is registered as a handle without a file and printed once in the footer, only on pages that contain a back button. No jQuery, no global
goBack()function.
Customise it
- Use your theme’s button style: add
class="wp-element-button"in a block theme, or your own class. - Fallback to the previous archive instead of the home page: pass the archive URL, for example
fallback="/blog/". - Inside a PHP template call
echo do_shortcode( '[dpc_back_button]' );.
Gotchas
- Sites that send
Referrer-Policy: no-referrerleavedocument.referrerempty, so the button always opens the fallback URL. - After a form submission with a redirect, going back can return to the form. Use a fixed fallback URL for those pages.
- Full-page caching is fine: the decision is made in the browser.
In the Scripts Organizer library Import it with one click from Scripts Organizer.