Redirection 301 and 302 in WordPress

There are times in which you may need to reorganize the content on your site, reassigning pages and articles to new topics or changing their URL. For instance you may want to refine a title or to reassign a post to a different (or new) category. The latter typically when a tag recurs so often that it should be upgraded to a category status.

Those operations may affect the permalink of the article, and therefore putting visitors who bookmarked your post on a route to an unpleasant 404 error. Same for search engines: they may serve the old URL on search results.

When the URL of a page changes, the SEO value accumulated by that page is also lost. The best way to preserve it consists in notifying Search Engines that the resource is in fact still available, but at a new URL.

There are various solutions to achieve that goal. Personally I prefer to act via the file .htaccess and/or via a template page and a dedicated, simple function. But first, what is the difference between a 301 and a 302 redirection?

By the way, you can also sign up at the bottom of the page for receiving new articles and blog entries directly via email.

Changing the url of a page can cause havoc

WordPress has an efficient and trivial solution for managing permalink. And often, if you notice, it can resolve by itself the change of a permalink to a post.

However, let us assume that you have an article under the category “Caffeine”, and at some point you decide that it has to belong to the category “Addiction”. Also, you realise that the title of the article is misleading, so you change that as well.

Before the permalink of the page may have been:

http://yoursite.com/caffeine/coffee-is-good

And later it becomes:

http://yoursite.com/addiction/cant-live-without-coffee

At this point, since the SEO value of a page (its rank and other parameters) is linked to its previous url, you likely lost it. If you want to save it you have to notify search engines that the address of the page has changed, providing the new URL, and therefore transferring the rank to the new url.

Status 301 or 302?

Search Engines are machines and we talk to them through status codes and numbers. The status codes for redirections are typically 301 and 302, where:

  • 301 is a permanent relocation, for instance when the page moves to a different domain.
  • 302 is a temporary relocation, implying that the page will be accessible in future at its original url, for instance when the site undergoes a phase of maintenance.

We notify Search Engines that a content has moved speaking their language. In the case of a whole site moving at a new domain, I would resort to the file .htaccess.

redirectMatch 301 ^/ http://newsite.com

Or preserving the permalink structure.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.oldsite.com$ [NC]
RewriteRule ^(.*)$ http://www.newsite.com/$1 [R=301,L]

But let us say you just need to redirect our article about coffee and caffeine to the new URL, and you want to use the file .htaccess for doing so. Then the following line will be sufficient.

Redirect 301 /caffeine/coffee-is-good http://yoursite.com/addiction/coffee-is-a-necessity

As told above, you can also use a code 302 instead of 301 if the relocation is only temporary, and you are confident to cure your caffeine addiction.

A more flexible approach for blogging

However, what if you need a more flexible and reusable method? When I decided to give a new start to my personal blog, I had several articles that, even if interesting by topic, were in desperate need of a rewriting. In few cases I had to change title and permalink to the page. Obviously I wanted to transfer the SEO value of the old pages, into the new one.

In the case of the article you are reading right now (and thanks for doing so) I summed up two old posts, into a new one.

So, how did I do?

WordPress has a appropriate function for the purpose and therefore it is smart to resort to it. However, I wanted a very trivial procedure for redirecting contents directly from the Dashboard without losing the original entries. So I decided to go for a small custom function and a specific Custom Field (that I defined “redirect” – pretty straight forward, huh?).

Redirecting a Post Type

In order to easily redirect an visit to a page that has been moved, I now resort to the function here below. It accepts an URL and as optional a value for the status code (301, or 302). If no code is provided, the function assumes a default 302.

Those values have to be passed by via Custom Field as told previously, like so:

1. http://site.com/page-title
2. 301 http://site.com/page-title
3. 302 http://site.com/page-title
4. http://site.com/page-title 302

Pick up one of the lines above. They all redirect to http://site.com/page-title. And here is the function that makes it possible. Copy and paste it into the file functions.php, usually located into your theme folder.

/*------------------------------------------------------*/
/*	my_redirect */
/*------------------------------------------------------*//*
	It redirects a resource to a new location.

	By default, the status code is set as 302 for temporary redirection,
	or use 301 for permanent redirection.
	
	The function requires a custom field in order to take action.
	Otherwise it will go silent.
	
	Custom Field Key -> 'redirect'
	Accepted Values (status code separated by space from the url, if provided):
		-> 'http://site.com/page-title'
		-> '301 http://site.com/page-title'
		-> '302 http://site.com/page-title'
		-> 'http://site.com/page-title 302'
		
	The status code has to be 301, or 302. Default 302.
	
	Note: It needs to be on top of everything, before the doctype. Otherwise
	you will get a "Warning Cannot modify header information - ..."
	
	Author: http://carlorizzante.com
	*/

if ( ! function_exists('my_redirect')) {
function my_redirect( $url = '', $status = 302 ) {
	
	global $post;
	$protocols = array( 'http', 'https');
	$redirect = get_post_meta($post->ID, 'redirect', true);
	
	if ( $redirect ) {
		$parts = explode(' ', $redirect);
		if ( is_array($parts)) {
			foreach ( $parts as $k => $v ) {
				if ( strlen($v) == 3 )	$status = $v;
				if ( strlen($v) > 3 ) $url = esc_url($v, $protocols);
			}
		}
		if ( isset($url) && ! empty($url)) {
			wp_redirect( $url, $status );
			exit();
		}
	}
}} // END my_redirect

Now, where to use the function and how? For it to be effective on posts it has to be placed in the file single.php. That file is likely located inside the theme folder of your choice.

../wp-content/themes/your-theme/single.php

Open the file with a proper Editor for coding (TextEdit or Notepad will do a decent job), and add the function before anything else could be executed. Like so.

< ?php /* Default Post Template */
my_redirect();
get_header(); ?>

	<div id="content" class="site-content" role="main">
	< ?php // the loop as usual... ?>
	...few lines later...
	</div><!-- END #content .site-content -->

Setting up custom fields

If you are a bit lost with the concept of Custom Fields, follow me, it is very simple to set them up on your WordPress site.

From the Post Editor (or Page Editor) click on the gray label on the top right of the page, with the title Screen Options. The click will cause panel to slide down, with few additional options. In there, check the one called Custom Fields.

Custom-Fields-01

Now, scrolling down the page a little, you should find the panel for setting up Custom Fields. On the field Name digit “redirect”, and on the field Value digit the url to where redirect that specific post of page. Optionally add a status code separated by a simple space from the url.

Custom-Fields-02

That should do the trick.

Redirecting a page

The procedure explained above works well for posts as well for pages. For redirecting a page you have to modify the file page.php similarly than what we saw above for single.php.

Conclusion

Hopefully this short explanation will help you in dealing with redirection and SEO.

Feel free to drop me a line or add a comment if you need more help on the topic. Or if you have a better methodology. And as usual, thanks for reading.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>