| |

How to warn Users before opening External Links in WordPress: A Practical Guide

I wanted visitors on WebberZone.com and ajaydsouza.comOpens in a new window to have a clear visual signal when a link was about to take them off-site. The difference between an internal link and an outbound one isn’t always obvious, especially with descriptive anchor text.

I also like building plugins, so I built WebberZone Link Warnings to handle it.

This guide covers installation, warning methods, domain exclusions, force-external rules, and post type control.

Installing the Link Warnings plugin

From WP-Admin:

  1. Go to Plugins > Add New.
  2. Search for WebberZone Link Warnings.
  3. Click Install Now, then Activate.

Manual install:

  1. Download webberzone-link-warnings.zip
  2. Upload webberzone-link-warnings to /wp-content/plugins/. You can also upload the file in the Plugins > Add New screen.
  3. Activate it under Plugins.

How Coverage Works

I designed WZLW to process links in two layers.

PHP handles post content at render time using WP_HTML_Tag_Processor. That alone misses too much because content filters don’t see menus, widgets, or footers.

So a JavaScript pass runs after the page loads and applies the same rules across the page.

Warnings appear across the whole page, not just inside the_content. The following class rules work in both layers:

  • wzlw-force-external
  • wzlw-force-external-wrapper
  • wzlw-no-icon
  • wzlw-no-icon-wrapper

The browser-side pass also honors domain exclusions.

Running the Setup Wizard

On activation, an admin notice offers a setup wizard. I’d recommend using it rather than jumping straight into the settings screen. You can also trigger the setup wizard by tapping the button at the bottom of the settings screen.

The wizard covers:

  1. Warning method
  2. Link scope
  3. Visual indicators
  4. Modal or redirect configuration

You can adjust everything later under Settings > Link Warnings.

Choosing a Warning Method

WZLW supports three approaches.

  • Inline indicator appends an icon or label beside affected links. No JavaScript is needed for the indicator itself.
  • Modal dialog intercepts the click and asks the visitor to confirm before leaving your site.
  • Redirect screen sends the visitor to an intermediate page before forwarding them onward.

You can combine inline indicators with either a modal or a redirect.

The default setup is inline + modal, which is how I have it on my own sites.

Configuring the Inline Indicator

Go to Settings > Link Warnings > Display.

The Icon Style dropdown includes several Unicode presets. I leave the default (↗) in place because it works cleanly across most themes.

If needed, select Custom and enter your own Unicode character or emoji.

The Indicator Type setting controls whether visitors see:

  • Icon only
  • Text only
  • Icon + text
  • Screen-reader-only output

To suppress indicators on a specific link:

<a href="https://example.com" class="wzlw-no-icon">Link text</a>

To suppress them across a block:

<div class="wzlw-no-icon-wrapper">
  <a href="https://example.com">Link one</a>
  <a href="https://example.org">Link two</a>
</div>

The modal or redirect still fires even when the icon is hidden.

Setting Up the Modal Dialog

The modal settings live under Settings > Link Warnings > Display.

You can customize:

  • Heading text
  • Body copy
  • Continue/Cancel labels

I’d recommend rewriting the default body text. Generic warning copy tends to read like a banking security alert.

The modal traps keyboard focus correctly and hides background content from screen readers.

Using the Redirect Screen

The redirect settings sit alongside the other display settings.

Countdown duration controls how long visitors wait before forwarding. Set it to 0 if you prefer an explicit click on Continue.

I prefer the explicit click. Auto-forwarding feels surreptitious.

WZLW signs redirect URLs with HMAC validation so the endpoint can’t be abused as an open redirect.

For full design control, copy this template into your theme:

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

Theme overrides survive plugin updates.

Excluding Trusted Domains

Go to Settings > Link Warnings > Advanced.

Add one domain per line under Domain Exclusions.

Plain entries match exact domains:

example.com

Wildcard entries match subdomains:

*.example.com

You’ll usually want both entries if you need to exclude the root domain and all subdomains.

Forcing Links to Be Treated as External

Some links look internal but still lead visitors elsewhere. Affiliate cloaking and /go/ redirects are common examples.

To force a single link:

<a href="/go/partner/" class="wzlw-force-external">Partner link</a>

To force an entire block:

<div class="wzlw-force-external-wrapper">
  <a href="/go/product-a/">Product A</a>
  <a href="/go/product-b/">Product B</a>
</div>

These rules apply everywhere on the page. Menus and footers included.

Controlling Which Post Types Are Affected

The PHP content pass is limited to the post types you select under Settings > Link Warnings > General.

I usually leave the default untouched. On sites with large affiliate-heavy sections, I sometimes scope processing to specific post types to keep render-time work focused.

The browser-side pass still scans the fully rendered page, so menus and footer links continue to work regardless.

Troubleshooting

Icons appear on internal links

Check whether mapped domains or subdomain variants are missing from your exclusions.

Use both:

yourdomain.com
*.yourdomain.com

Warnings missing in menus or widgets

Check whether JavaScript is disabled or blocked by a caching layer.

Also, confirm the link isn’t inside wzlw-no-icon-wrapper.

Modal doesn’t fire

Clear caches and test in a fresh browser profile.

The Redirect screen doesn’t match the theme

Override redirect-screen.php inside your theme directory and customize it there.

Force-external links not triggering

Verify the class name under Settings > Link Warnings > Advanced matches the class applied to the link. Check that the domain isn’t excluded.

Conclusion

WZLW doesn’t modify stored content. It only changes the rendered output.

Deactivate it and your links return to exactly how they were. I made that decision deliberately: no cleanup routines and no database changes to undo.

If you run into anything not covered here, the support forum on WordPress.org is the right place to raise it.

Keep on publishing!

Leave a Reply

Your email address will not be published. Required fields are marked *