How To Remove "noopener noreferrer"

mackem

Test, Test, Test
Joined
Sep 6, 2018
Messages
40
Likes
93
Degree
0
So it seems that the latest version Wordpress is adding "noopener noreferrer" to every external link.

I've tried using the solution that @Ryuzaki proposed here and also this gist by Log1x and so far, the tag is still being included when I view the source.

The only thing that I've done differently is that I've included as a snippet (using the code Code Snippets plugin) rather than adding it directly to functions.php although this has never been an issue with any other new functions.

Any help would be greatly appriciated!
 

mackem

Test, Test, Test
Joined
Sep 6, 2018
Messages
40
Likes
93
Degree
0
Okay, I seem to have answered my own question with a little help from this post.

PHP:
//This code removes noreferrer from your new or updated posts
add_filter( 'wp_targeted_link_rel', 'my_targeted_link_rel_remove_noreferrer',999);
function my_targeted_link_rel_remove_noreferrer( $rel_values ) {
return preg_replace( '/noreferrer\s*/i', '', $rel_values );
}

//This code removes noopener from your new or updated posts
add_filter( 'wp_targeted_link_rel', 'my_targeted_link_rel_remove_noopener',999);
function my_targeted_link_rel_remove_noopener( $rel_values ) {
return preg_replace( '/noopener\s*/i', '', $rel_values );
}

//remove noreferrer on the frontend, *will still show up in the editor.*
function my_formatter($content) {
$replace = array(" noreferrer" => "" );
$new_content = strtr($content, $replace);
return $new_content;
}

//remove noopener on the frontend, *will still show up in the editor.*
function noopener_formatter($content) {
$replace = array("noopener" => "" );
$new_content = strtr($content, $replace);
return $new_content;
}

add_filter('the_content', 'noopener_formatter', 999);
add_filter('the_content', 'my_formatter', 999);
 
Joined
Jul 6, 2016
Messages
42
Likes
39
Degree
0
Just interested for myself, why are you removing it?
It doesn't seem to break affiliate links anymore and apparently it doesn't affect SEO.
 

Ryuzaki

女性以上のお金
Staff member
BuSo Pro
Digital Strategist
Joined
Sep 3, 2014
Messages
3,630
Likes
6,848
Degree
8
Yeah, with Gutenberg the old filter stopped working. It was for TinyMCE, which Gutenberg no longer uses. I think it even altered it for the Classic Editor at this point.

Just interested for myself, why are you removing it?
It doesn't seem to break affiliate links anymore and apparently it doesn't affect SEO.
Noopener is fine. It just stops the destination site from hijacking YOUR tab (reverse tabnabbing) when you have a user open a link with target="_blank".

Noreferrer is only there because some legacy browsers don't use Noopener yet, but support Noreferrer in a way that prevents tabnabbing. The problem is that it stops referrer data from being sent.

It can break affiliate links. Amazon apparently stepped in and put pressure on Wordpress to remove it last time, but it came back with Gutenberg. It doesn't stop programs where you have your ID's tagged to the URL with a parameter, but not all affiliate programs do that. Some just use the referring domain data, or at least demand it be there to validate the traffic (like Amazon), which gets blocked. They need to move beyond that anyways with HTTP / HTTPS and all that. But yeah it can still matter depending on the network.

EDIT #1:
I just confirmed that even if you remove "noreferrer" in the Block Editor, when you update the post later it will be re-added. So don't waste time manually removing it. Looks like when we update to the next version of Wordpress it just adds it back.

EDIT #2:
The code provided above works for the classic editor but not the block editor. There seems to be no current solution, hook, filter, whatever when it comes to Gutenshit.

EDIT #3:
wp_remove_targeted_link_rel_filters() was added in Wordpress 5.1, but hell if I can get it to work.
 

mackem

Test, Test, Test
Joined
Sep 6, 2018
Messages
40
Likes
93
Degree
0
@Ryuzaki thanks for taking a loook into this too. Seems the only way to get this working at the moment it to use the two functions at the bottom.
 

Ryuzaki

女性以上のお金
Staff member
BuSo Pro
Digital Strategist
Joined
Sep 3, 2014
Messages
3,630
Likes
6,848
Degree
8
@mackem, yeah, I'd rather not run a filter on the_content. Seems a bit demanding for what we're trying to do. I'm thinking that a client-side Javascript function is better. I'm going to implement that some point in the near future and will share it here. I'm guessing that they'll fix the problem of it re-adding 'noreferrer' even after we remove it, but until then I'll just let it sit in the database. Once they fix it we should be able to bulk-remove it in one go with a MySQL command.
 

mackem

Test, Test, Test
Joined
Sep 6, 2018
Messages
40
Likes
93
Degree
0
@Ryuzaki ah, I get where you're coming from here - think I was a little naive there about how much of an impact filtering the_content could have!
 

Cash Builder

BuSo Pro
Joined
Jan 14, 2017
Messages
322
Likes
349
Degree
2
Okay, I seem to have answered my own question with a little help from this post.

PHP:
//This code removes noreferrer from your new or updated posts
add_filter( 'wp_targeted_link_rel', 'my_targeted_link_rel_remove_noreferrer',999);
function my_targeted_link_rel_remove_noreferrer( $rel_values ) {
return preg_replace( '/noreferrer\s*/i', '', $rel_values );
}

//This code removes noopener from your new or updated posts
add_filter( 'wp_targeted_link_rel', 'my_targeted_link_rel_remove_noopener',999);
function my_targeted_link_rel_remove_noopener( $rel_values ) {
return preg_replace( '/noopener\s*/i', '', $rel_values );
}

//remove noreferrer on the frontend, *will still show up in the editor.*
function my_formatter($content) {
$replace = array(" noreferrer" => "" );
$new_content = strtr($content, $replace);
return $new_content;
}

//remove noopener on the frontend, *will still show up in the editor.*
function noopener_formatter($content) {
$replace = array("noopener" => "" );
$new_content = strtr($content, $replace);
return $new_content;
}

add_filter('the_content', 'noopener_formatter', 999);
add_filter('the_content', 'my_formatter', 999);
Just to double check, is the first function fine to use? I just added it to my site and it successfully keeps "norefferer" from coming back after I manually delete it.
 

Cash Builder

BuSo Pro
Joined
Jan 14, 2017
Messages
322
Likes
349
Degree
2
@Cash Builder I don't think it's harmful, I think it's seen as best practice not to modify "the_content" directly.
Thanks, I'm testing out a new affiliate program and I've not had any clicks register in the past 3 days. I'm thinking "noreferrer" could be the problem. I'll use this until a better solution comes along.
 

Ryuzaki

女性以上のお金
Staff member
BuSo Pro
Digital Strategist
Joined
Sep 3, 2014
Messages
3,630
Likes
6,848
Degree
8
Bro's and Brosette's,

There's nothing that works for this issue satisfactorily. I've tried every function on the net, none work. Wordpress provides wp_remove_targeted_link_rel_filters() and wp_targeted_link_rel() and similar options that are all acknowledged as broken in their trac and not a priority to fix.

Filtering and running regex on the_content() is not acceptible to me, even if I'm caching. It's expensive and dirty.

I ran a SQL command on the database to search and replace 'noreferrer' which was awesome, until I edited a post and resaved it. Suddenly it was back.

So that leaves us with one decent answer, which is to just eradicate noreferrer on the client side. Later, (a year or two from now?) once they fix that "targeted link filter" we can go back and get rid of it for real. This solution I just cooked up will work in the mean time.

Since every Wordpress installation comes with jQuery and there's nothing you can do about it, I wrote a piece of jQuery:

Code:
// Removes 'noreferrer' From All Link Rel Attributes on target="_blank" Links on Gutenberg
// June 26, 2019 - Explained at Builder Society:
// https://www.buildersociety.com/threads/how-to-remove-noopener-noreferrer.4242/#post-44552
$(document).ready(function() {
    $('a[rel~="noreferrer"]').each(function() {
        $this = $(this);
        var oldRel = $this.attr('rel');
        var newRel = oldRel.replace('noreferrer', '');
        newRel = $.trim(newRel);
        newRel = newRel.replace(/\s\s+/g, ' ');
        $this.attr('rel', newRel);
    });
});
I've confirmed it working and present to you the proof below, straight from my browser console:



Let me explain the code so you're not flying blind.

$(document).ready(function() {
This part says "don't run this code until the document is ready" meaning that the DOM has loaded the source code and the noreferrer's are in the browser. Images and other crap may not have loaded yet. This is the earliest we can kill off the noreferrers. There's zero chance a human clicks one of your links while noreferrer is still there in this setup.

$('a[rel~="noreferrer"]').each(function() {
This part says "select every anchor tag, but narrow it down so that you not only select just the ones with a rel attribute, but only ones that have the phrase "noreferrer" in them. This way keeps us from doing unnecessarily "expensive" stuff. We're keeping it minimal and efficient. The .each part allows us to run a callback function on each link. It loops through them one at a time.

$this = $(this);
We're caching the jQuery selector for each link since we use it multiple times. This is more efficient. You don't have to do it but being wasteful sucks.

var oldRel = $this.attr('rel');
This saves the text of the rel attribute as a text string in the variable oldRel.

var newRel = oldRel.replace('noreferrer', '');
This finds "noreferrer" in the oldRel text string and replaces it with nothing, saving the new version of the rel attribute in a new variable called newRel.

newRel = $.trim(newRel);
Since we're guaranteed to have extra whitespace at the end of the strings, like when "noopener noreferrer" becomes "noopener " (note the extra space still there), this gets rid of that. We want clean HTML, even if having the space there is valid.

newRel = newRel.replace(/\s\s+/g, ' ');
There are scenarios like "noopener noreferrer nofollow" that will get all this work done on it and end up as "noopener nofollow" (two spaces between those words). This little chunk of Regex finds double spaces and turns them into a single space. It actually finds new lines and tabs too, but it's not much more expensive than just finding spaces and it leaves us with readable code, which is more important than a 5 millisecond saving in this case.

$this.attr('rel', newRel);
This goes back to our cached link and sets the rel attribute to the new value, which is the variable newRel.

_________

It's extremely possible I've missed some detail so please speak up if you see something. Otherwise, happy affiliate marketing!

Note: To use this, you're going to have to either add it to a new .JS file and enqueue it, hardcode it in your footer, or maybe you have a theme options panel you can paste it into.