Converting external links to open in a new window automagically.

First, the code. Add this as a plugin, an mu-plugin, or a snippet straight into functions.php

<?php
/**
* Filters given content to add target="_blank" to external links.
*
* @see https://developer.wordpress.org/reference/files/wp-includes/html-api/class-wp-html-tag-processor.php/
* @see https://adamadam.blog/2023/02/16/how-to-modify-html-in-a-php-wordpress-plugin-using-the-new-tag-processor-api/
* @param string $content Content of the post.
* @return string
*/
function prefix_external_link_target_blank( $content ): string {
// Instantiate the processor.
$processor = new WP_HTML_Tag_Processor( $content );
// Get the domain of the site without scheme.
$site_domain = wp_parse_url( site_url(), PHP_URL_HOST );
// Loop through all the A tags and parse href to see if it's an external link.
while ( $processor->next_tag( 'A' ) ) {
$href = $processor->get_attribute( 'href' );
$root_domain = wp_parse_url( $href, PHP_URL_HOST );
// If root domain is null, it's an internal link (no host), skip.
if ( null === $root_domain ) {
continue;
}
// If the root domain is not the same as the site domain, it's an external link.
if ( $root_domain !== $site_domain ) {
$processor->set_attribute( 'target', '_blank' );
$processor->set_attribute( 'rel', 'nofollow external noopener noreferrer' );
}
}
return $processor->get_updated_html();
}
add_filter( 'the_content', 'prefix_external_link_target_blank', 999 );
view raw functions.php hosted with ❤ by GitHub

I’m really excited by all of the upcoming HTML modification API’s in WordPress. Since 6.2 we’ve had the WordPress HTML Tag Processor API which allows parsing HTML without REGEX, and then allows modifying attributes on elements.

That’s basically what this snippet does, parses post content, searches for links, compares the URL to the site URL, and alters the target attribute if it’s deemed to be an external link.

In WordPress 6.4 there’s updates coming and a new HTML processor which should further simplify markup modification directly from PHP without using REGEX.

Leave a comment