fbpx

Automatically Add Link Attributes in WordPress

Published:
Last Updated: Nov 23, 2022

Written by

This article contains affiliate links, which means that I may receive a commission if you make a purchase using these links.

Last year, Google announced new link attributes to help the search engine (and end-users) better identify sponsored, monetized and user-generated links.

In this blog post, I’ll share with you the code snippet I added to my blog to:

  1. Automatically rewrite existing links and add the rel=“sponsored” attribute.
  2. Add an asterisk (*) to all affiliate links to let visitors know which links I’ve monetized.

The code that I’ll share with you today can be easily customized to match your individual use cases.

Google’s Announcement Regarding New Attributes

Source code with link attribute
One of my affiliate links with the rel=sponsored attribute.

On September 10th, 2019, Google announced on the official Google Webmaster Central blog how the search engine behemoth was planning to evolve the old rel=“nofollow” tag.

Specifically, Google introduced two new link attributes to replace the old nofollow tag in certain cases.

Until recently, I used the External Links plugin to mark all affiliate and sponsored links as nofollow links. I did the same for links visitors placed inside of comments.

Going forward, Google wants publishers to use the following new tags:

  • rel=“sponsored” — use the “sponsored” attribute to identify links on your site that were created as part of advertisements, sponsorships or other compensation agreements.
  • rel=“ugc” — UGC stands for user generated content, and the “ugc” attribute value is recommended for links within user generated content, such as comments and forum posts.

You can continue using rel=“nofollow” for any links that you don’t want Google to follow. 

Note that link attributes are hints for Google but using them won’t guarantee that Google will honor them.

Why Link Attributes Are Important for SEO

Link attributes help Google’s crawlers understand your content. The more transparent you are with Google (and your users), the better it will be in the long run.

Sure, you might be able to trick Google for a while. But the search engine has thousands of very smart engineers on its payroll that will figure out if you’re using black-hat techniques.

So I decided a long time ago to make it as easy as possible for Google to understand my content.

At the same time, I also try to be as transparent as possible with my visitors and users. They should know how I monetize my blog and that some of the links they click on might be affiliate links. That’s only fair.

Rewrite Links in WordPress Programmatically

Both Google and visitors can identify this as an affiliate link
Both Google and visitors can identify this as an affiliate link.

I use WordPress for my blog and, until recently, I used the External Links WordPress plugin to help rewrite some of my external links — specifically affiliate links.

While the plugin authors added support for Google’s new link attributes relatively quickly, they did so in a manner that wasn’t flexible enough for what I needed.

I didn’t want to add rel=“sponsored” to all external links, only to some. While the plugin had a way to define “exceptions” to the general rule by using pattern matching, those exceptions could only be tagged with the follow/nofollow attributes, not with “sponsored.”

Long story short, I decided to write my own WordPress filter that would give me the flexibility I needed.

My ultimate goal was to rewrite all links inside of posts and pages that matched a predefined list of patterns.

For example, most of my affiliate links are redirects that follow the /go/abc pattern. For example, /go/sanebox redirects to:

https://www.sanebox.com/?mbsy_source=29ec865a-f993-4c27-a46e-e159811d1818&mbsy_exp=Thu%2C+02+Jul+2020+17%3A53%3A28+GMT&campaignid=1914&mbsy=vTtjl.

With that in mind, all I needed was:

  • A piece of code that would register as a standard WordPress content filter.
  • A regular expression that would find links inside the content.
  • A function that would compare the found links against a predefined pattern.
  • To replace/rewrite the link by adding the rel=“sponsored” attribute.

For all links that didn’t match my pattern, I added the rel=“follow” attribute.

To add the code snippet to WordPress without modifying my functions.php file, I used the super-convenient Code Snippets plugin.

Full Code Snippet

Below is the full code snippet I used to make the magic happen. Don’t worry — I’ll walk you through it so that you understand what each line does.

function rewrite_affiliate_links($content) {
  $content = preg_replace_callback(
  '/<a[^>]*href=["|\']([^"|\']*)["|\'][^>]*>([^<]*)<\/a>/i',
    function($m) {
		$Sponsored_URLS = explode(",","Amazon.com,amzn.to,shareasale.com,hsselite.7eer.net,tkqlhce.com,jdoqocy.com,dpbolvw.net,awltovhc.com,tqlkg.com,lduhtrp.net,anrdoezrs.net,ftjcfx.com,7eer.net,refersion.com,avantlink.com,/go/,www.sunstar.com.ph,www.alliedmarketresearch.com,www.theyucatantimes.com,rubikicks.com,superfoodprofiles.com,amplifi.com,performancelab.com");
		$i = 0;
		$j = count($Sponsored_URLS);
		while ($i < $j) { ;
			if ((strpos(strtolower($m[1]), strtolower($Sponsored_URLS[$i])) !== false)) {
				$match = "yes";        		
    		}
    		$i++;
    	}
    	if ($match == "yes") {
    		return '<a href="'.$m[1].'" rel="sponsored noopener" target="_blank">'.$m[2].'*</a>';
    	} else {
		  	if ((strpos(strtolower($m[1]), $_SERVER['HTTP_HOST']) !== false) || (substr($m[1],0,1) == "#")) {
			  return $m[0];
			} else {
			  return '<a href="'.$m[1].'" rel="follow noopener" target="_blank">'.$m[2].'</a>';
			}
    	}
    },
$content);

  return $content;
}

add_filter('the_content', 'rewrite_affiliate_links', 100);  

The Regular Expression

The most critical part of this code is the regular expression (regex) that filters out links in the WordPress content:

$content = preg_replace_callback(
  '/<a[^>]*href=["|']([^"|']*)["|'][^>]*>([^<]*)</a>/i',

I’m by no means a regex wizard, but what the above line does is look for a pattern that matches <a href=“XYZ”></a>. It matches anything that’s between <a and </a> as long as it contains the href attribute. In other words, it would also find a link like <a href=“michaelkummer.com” rel=“nofollow”>My blog</a>.

What it doesn’t find are links that have embedded HTML tags. For example, the now-discontinued WP Review plugin placed <span> tags inside the link structure, which throws the regex off.

What you might have noticed is that I’m using the preg_replace_callback() function of PHP. That allows me to pipe the matched URL directly into a rewrite function.

The Rewrite Function

The rewrite function takes the matched URL as an input argument and then compares the URL against each member of an array that contains patterns for all my affiliate URLs.

Note that array elements can be partial URLs. For example, /go/ would also match /go/sanebox.

To prevent any mismatches from different spellings of the URLs (i.e., upper or lower case), I use the strtolower() function to convert everything to lower case before doing the comparison.

If the URL provided by my regex matches a URL from the content, I reassemble the URL and add the rel=“sponsored noopener” and target=“_blank” attributes.

Additionally, I add an asterisk to the end of the text that’s encapsulated by the <a></a> link tags. That way, all my visitors immediately see if a link is monetized or not.

I think that greatly improves transparency and trust.

However, if the URL found in the content doesn’t match any of my affiliated URL patterns, and if it’s not an internal link, then I rewrite the URL to contain the rel=“follow noopener” attribute.

I use the global variable $_SERVER[‘HTTP_HOST’] to see if the URL contains my server’s hostname. If it does, it’s an internal URL.

The WordPress Filter

To register my fancy function as a filter in WordPress, I have to use the add_filter() function. It takes the WordPress content (the_content), the function name (rewrite_affiliate_links, in my case), and the optional priority as arguments.

I chose a low priority (high number) to make sure my filter gets called as late as possible and after any other output/content filters get called.

How to Add the Code to WordPress

All my code snippets
I use the Code Snippets plugin for different use cases.

Adding the above code to WordPress is relatively easy if you use the Code Snippets plugin.

Before you make changes to your production or live site, I always recommend making a backup that you can easily revert to. Even better, I recommend using a staging site. I use Flywheel as my hosting provider and they offer a staging site that I can experiment with. If I mess up, it doesn’t bring down my live page!

Here’s how it works:

  1. Install and activate the Code Snippets plugin (Log in to your WordPress backend, go to Plugins, click on Add New and search for Code Snippets).
  2. Go to Snippets > Add New, paste the code from above, and give your snippet a name.
  3. Change the list of URL patterns to match your affiliate URLs.
  4. If the code snippet editor doesn’t show any syntax errors, click on Save Changes and Activate.
  5. Open one of your posts or pages that contains an affiliate link and confirm that you see the *. Alternatively, you can inspect the source code of the page and make sure the link has the proper rel attributes.

How to Support Linked Images

The code snippet above works great for text links but not for linked images. After having done some research and getting help from the awesome community on stackoverflow, I’m happy to share an updated function that works for both text links and images:

function rewrite_affiliate_links($content) {
  $sponsoredLinks = [
    "Amazon.com",
    "amzn.to",
    "shareasale.com",
    "hsselite.7eer.net",
    "tkqlhce.com",
    "jdoqocy.com",
    "dpbolvw.net",
    "awltovhc.com",
    "tqlkg.com",
    "lduhtrp.net",
    "anrdoezrs.net",
    "ftjcfx.com",
    "7eer.net",
    "refersion.com",
    "avantlink.com",
    "\/go\/",
    "www.sunstar.com.ph",
    "www.alliedmarketresearch.com",
    "www.theyucatantimes.com",
    "rubikicks.com",
    "superfoodprofiles.com",
    "amplifi.com",
    "performancelab.com",
  ];

  $sponsoredLinksPrepared = implode('|', $sponsoredLinks);
  $anchorRegex = "/<a.*?href=(?:\"|')(.*?(?:{$sponsoredLinksPrepared}).*?)(?:\"|').*?>(.*?)<\/a>/i";
  $anchoreReplacement = '<a href="$1" rel="sponsored noopener" target="_blank">$2*</a>';
  $imgRegex = "/<img.*?src=(?:\"|')(.*?(?:{$sponsoredLinksPrepared}).*?)(?:\"|') (.*?)>/i";
  $imgReplacement = '<img src="$1" rel="sponsored noopener" $2>';

  $content = preg_replace($anchorRegex, $anchoreReplacement, $content);
  $content = preg_replace($imgRegex, $imgReplacement, $content);

  return $content;
}

Frequently Asked Questions

What are sponsored links?

Google considers any links that were created as part of an advertisement, sponsorship or other compensation agreement to be “sponsored.” That includes any links to brands or products you have an affiliate relationship with. Of course, that also includes paid links in sponsored articles.

What happens if I continue using nofollow instead of sponsored links attributes for affiliate links?

Probably nothing in the short term, because Google has just introduced the “sponsored” attribute and the search engine usually has generous grace periods for changes of this nature. However, if you play at the mercy of Google and generate most of your traffic from organic search, I’d recommend following Google’s recommendations to the letter as soon as possible.

What is considered user-generated content (UGC)?

User generated content is any content your visitors or users contribute to the site. A good example would be comments on blog articles. Another example would be user-submitted recipes on a food blog.

Wrap-Up

How to automatically add link attributes in WordPress
YouTube video: How to automatically add link attributes in WordPress

While the code above is relatively easy to implement and adapt, I realize that a plugin with a graphical user interface would be even nicer. I submitted a feature request with the author of the External Links plugin, but after that I decided to go the snippet route. That way, I retain flexibility and I can make changes as my requirements evolve.

If you found my code useful and made it work on your webpage or blog, let me know by leaving a comment below. If it didn’t work for you, let me know that as well — maybe I can help you get it working.

36 thoughts on “Automatically Add Link Attributes in WordPress”

  1. Trying to use Alissa’s snippet, but it doesn’t seem correct. I’m not sure where her 3 capture groups are supposed to be coming from.

    Did any of her snippet get filtered out by your anti-spam plugin?

    Reply
  2. Hi Michael, the code works perfectly. Thanks for that. I need one help. The code removes the class attribute from the links. Is there any way to keep them?

    Reply
  3. Thanks so much for this! I’ve been fiddling with it and think I found an approach that doesn’t strip the styling, classes, and other attributes from the links. This would solve the problem mentioned above with turning all button styles into link styles and vice versa.

    My new approach looks within the tag for one of the affiliate links, and if one is found, it captures the parts before and after the “rel=”. Then, to reassemble the new link, it concatenates those two chunks with the new rel=”…” in between. So in theory this should work for any kind of link, including those with images inside, while preserving any classes or attributes that were associated with the link.

    Here’s the code:

    $anchorRegex = “/(.*?)/i”;
    $anchorReplacement = ‘$1 rel=”sponsored noopener” $3’;
    $content = preg_replace($anchorRegex, $anchorReplacement, $content);

    Disclaimer: I’m totally not an expert at this! It works on my site but use at your own risk. I would not be at all surprised if there are edge cases it doesn’t work for. :)

    Reply
    • Thanks for sharing the code Alissa, I appreciate it!

      PS: Apologies for the late reply. Your comment got accidentally deleted by my anti-spam plugin and I just found out about it.

      Reply
  4. Hi Michael,

    Thank you for the detailed walkthrough! I’m curious to know how can I implement this to images as well?

    Reply
  5. How to change in Woocommerce product links which are import from the Woozone and this code does not work on woocommerce product pages. What should I do?

    Reply
  6. Hey Michael,

    Great code snippet. It works as it should. But it removes the styling class from the affiliate button. Not sure why it is happening. Can you suggest a fix? I am using AAWP plugin.

    Reply
    • Hi Linda,

      I’m not familiar with the AAWP plugin but I could imagine that the button uses a CSS class for styling. Find out what the styling class is and add class=”CLASSNAME” to the link.

      Can you send me a link to the page that shows the working button?

      Cheers,
      Michael

      Reply
      • The Code is Really Flawless and working fine. But since I am not an expert in this field I am having a problem with aawp button…

        AAWP affiliate Button is not showing the instead of a plain link text.

        Reply
          • Try adding the AAWP classes to the code:

            So, the line of code that starts with the word RETURN would read:

            ...target="_blank" class="aawp-button aawp-button--buy aawp-button aawp-button--amazon aawp-button--icon aawp-button--icon-amazon-black" rel="sponsored noopener nofollow ugc">...

            The better option is to tell AAWP to add the “sponsored” tag to their links.

            Cheers,
            Michael

          • Bro, i tried with the code but the fact is the code makes everything a button.

            For example, It makes the aawp title link as a button too which I use in the table.

            Here is an example found in their live demo: https://getaawp.com/demo/

            When i applied the code and style CSS it does the job for the button and tags it as sponsored with correct styling, but it also makes the link and other things as buttons.

            Without the style CSS, it works perfectly with the links, making them sponsored tagged with no issue.

            Hope you understand. looking for your magical help bro :)

            Loads of love.

          • Hey Aarif,

            I don’t think my code is a great choice for styled links because it’s difficult to filter for all the different types of links this plugin uses.

            I would reach out to the plugin authors and ask them to add rel=sponsored to their links. If they aren’t willing to do that, you could edit the plugin files directly. If you send me the plugin files to install in my local environment, I can try and do that for you for a fee.

            Cheers,
            Michael

      • I tried To find out the class may be this one is the one… Would you please help me to solve the aawp button issue :)

        class=”aawp-button aawp-button–buy aawp-button aawp-button–amazon rounded shadow aawp-button–icon aawp-button–icon-black”

        Reply
      • Brother I am eagerly waiting for the solution of the AAWP button styling issue. Can you please help me and others :)

        Cheers,
        Aarif

        Reply
        • Bro i can’t figure where to place which code in your original code. As i said I’m really noob in technical field. Would you please elaborate more precisely. I’m stuck in the middle of process.

          Reply
          • Sorry man, I just realized that WP interpreted the HTML code I was pasting and the line didn’t make any sense.

            All I did was add the CLASS statement to the RETURN line, like you can see in the updated comment below.

        • I wanted to point out that we were able to solve this problem by changing the add_filter. Our coder replaced 100 with 5 so that it would load earlier and that resolved the plugin conflict. Just wanted to share that in case anyone else encounters other plugin conflicts.

          Reply
  7. With a free mind I found the cuprit right now: I had a comma too much in my list of URLs :) Your script is flawless!

    Thank you so much again!

    Reply
  8. Hi Michael,

    first off: thanks for that script! It was exactly what I was looking for.

    It seems to work on my site, all rel attributes get added an the * shows up. Unfortunately though, I get per modified link one error message:

    Warning: strpos(): Empty needle in /plugins/code-snippets/php/snippet-ops.php(446) : eval()’d code on line 9

    Line 9 beeing: if ((strpos(strtolower($m[1]), strtolower($Sponsored_URLS[$i])) !== false)) {

    It tried to google the error but I am not good with scripts. Could you give me a hint? That would be much appreciated!

    Thanks a lot,
    Stephan

    Reply

Leave a Comment