This article is intended for advanced users and developers who want to modify the behavior of the Redirect screen in WebberZone Link Warnings.

When the warning method is set to Redirect screen or Inline indicators + Redirect screen, clicking an external link opens an interstitial page before the user reaches the external destination. This page shows the destination URL, a message, and a countdown timer.

How the redirect screen works

  1. The plugin registers a rewrite rule that maps external-redirect/ to a custom query variable.
  2. When a user clicks a processed link, the frontend JavaScript navigates to the signed external-redirect/ URL. Links added outside post content receive their signed URLs through the plugin’s AJAX signing endpoint before navigation.
  3. On template_redirect, the plugin validates the signed destination URL and renders the redirect template.
  4. A separate JavaScript file (redirect.js) starts a countdown timer. When the countdown reaches zero, the browser automatically redirects to the external URL.
  5. If the user clicks anywhere on the page (except the “Continue to site” button) or presses any key (except Tab), the automatic countdown is canceled.

Redirect URL structure

The redirect URL is generated by Redirect_Handler::get_redirect_url():

https://yoursite.com/external-redirect/?url=<encoded-url>&wzlw_sig=<signature>

The destination URL is passed as a url query parameter, encoded with rawurlencode(). The wzlw_sig parameter contains an HMAC signature generated from the exact destination URL. Query parameters, fragments, and plus signs in the destination remain part of the signed value.

Open redirect protection

Redirect_Handler::is_valid_url() accepts a destination in any of these forms:

  • Root-relative paths with no host and no scheme (e.g. /go/product/) — treated as same-site and valid on their own. This covers cloaked affiliate redirect links marked with the Affiliate Link Class or Affiliate Link Wrapper Class, which point at internal paths. A scheme-bearing but host-less value (e.g. http:evil.com) is deliberately rejected here, since browsers resolve that against a remote host when the scheme differs from the page’s — an authority-less path is only trusted when the scheme is absent too.
  • Network-path references such as //example.com/page, which have a host but no scheme.
  • Absolute http and https URLs that pass filter_var() with FILTER_VALIDATE_URL. Same-site absolute URLs are valid because force-external and internal target="_blank" links can also use the redirect screen.

The HMAC signature authorizes the destination. The host does not need to differ from the site host. Values using other schemes, such as mailto:, or values that fail validation send the user to the site home page via wp_safe_redirect().

Template override

The default template is located at:

includes/templates/redirect-screen.php

To override it, copy the file to your theme (or child theme):

your-theme/webberzone-link-warnings/redirect-screen.php

The plugin checks for the template in the following order:

  1. your-theme/webberzone-link-warnings/redirect-screen.php
  2. your-theme/webberzone-link-warnings/redirect.php
  3. The plugin’s built-in template.

This uses WordPress’s locate_template(), so child themes take priority over parent themes.

Available template variables

The following variables are available inside the redirect template:

VariableTypeDescription
$destinationstringThe full external URL the user is being redirected to.
$messagestringThe redirect message configured in settings.
$domainstringThe host portion of the destination URL (e.g. example.com).
$countdownintThe countdown duration in seconds. 0 means auto-redirect is disabled.

Writing a custom template

A minimal custom template:

<?php
/**
 * Custom redirect screen template.
 *
 * @var string $destination Destination URL.
 * @var string $message     Redirect message.
 * @var string $domain      Destination domain.
 * @var int    $countdown   Countdown in seconds.
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

get_header();
?>
<div class="my-redirect-page">
    <h1>Leaving this site</h1>
    <p><?php echo esc_html( $message ); ?></p>
    <p>Destination: <strong><?php echo esc_html( $domain ); ?></strong></p>
    <p><a href="<?php echo esc_url( $destination ); ?>" rel="noopener noreferrer">Continue to site</a></p>
    <p><a href="<?php echo esc_url( wp_get_referer() ? wp_get_referer() : home_url() ); ?>">Go back</a></p>

    <?php if ( $countdown > 0 ) : ?>
        <p class="wzlw-redirect-countdown" aria-live="polite">
            Redirecting automatically in <span class="wzlw-countdown-number"><?php echo esc_html( $countdown ); ?></span> seconds...
        </p>
    <?php endif; ?>
</div>
<?php
get_footer();

The countdown JavaScript targets .wzlw-countdown-number to update the displayed number. If you remove or rename this class, the visual countdown will stop updating, though the redirect itself still fires after the configured duration.

Countdown behavior

The countdown is handled by redirect.js, which is enqueued automatically on the redirect page. It reads its configuration from a localized JavaScript object:

wzlwRedirect.destination // The external URL.
wzlwRedirect.countdown   // The countdown duration in seconds.

Disabling auto-redirect

Set Redirect Countdown to 0 in the plugin settings. The countdown element will not be rendered, and the JavaScript will not start a timer. The user must click “Continue to site” manually.

Cancelling the countdown

The countdown is canceled automatically if the user:

  • Clicks anywhere on the page (except the “Continue to site” link).
  • Presses any key except Tab.

This prevents the redirect from firing while the user is interacting with the page.

Redirect screen assets

The plugin enqueues the following assets on the redirect page only:

HandleFilePurpose
wzlw-redirect (CSS)includes/assets/css/redirect.cssPage layout, card, buttons, countdown animation.
wzlw-redirect (JS)includes/assets/js/redirect.jsCountdown timer and auto-redirect logic.

Both assets respect SCRIPT_DEBUG (loading unminified versions when enabled) and is_rtl() (loading RTL stylesheets when appropriate).

If you are using a fully custom template and do not need the default styles, you can dequeue them:

add_action( 'wp_enqueue_scripts', function () {
    if ( get_query_var( 'wzlw_redirect' ) ) {
        wp_dequeue_style( 'wzlw-redirect' );
    }
}, 20 );

Keep the JavaScript enqueued to ensure the countdown functions. If you are implementing your own countdown logic, you can dequeue the script as well.

Styling the default template with CSS

If you do not need a full template override, you can restyle the default redirect screen using CSS custom properties. See the Styling guide for the full list of redirect-related custom properties and class names.

Was this article helpful?