Programmatically 301 redirect by url

There are times when you need to remove posts from your website and want to redirect them to another post. You can simply do this by checking the old post’s ID and set a 301 redirect to another post and keep the old post in your database. This basically gives the right result, but with larger projects your database will eventually become messy if you don’t remove the old post in the end.

I will first give an example of how a 301 redirect by checking the post ID can be done.

/**
 * Creates 301 redirects by post ID
 */
function redirect_by_post_id() {

   // Is single Post
   if ( is_single() ) {
      global $post;
      if ( 123 === $post->ID ) {
         $redirect = get_permalink( 345 );
         wp_redirect( $redirect, 301 );
         exit;
      }
   }
   
}
add_action( 'template_redirect', 'redirect_by_post_id' );

The following example shows how to check the server request uri and make a 301 redirect when the url matches.

/**
 * Creates 301 redirects by request uri
 */
function redirect_by_request_uri() {

   if ( isset( $_SERVER['REQUEST_URI'] ) ) {

      // Store uri and create array of uri parts
      $request_uri = $_SERVER['REQUEST_URI'];
      $parts = explode( '/', $request_uri );

      // Check post slug
      if ( strpos( $parts[1], 'your-post-slug' ) !== false ) {
         $redirect = get_permalink( 345 );
         wp_redirect( $redirect, 301 );
         exit;
      }
         
   }
}
add_action( 'template_redirect', 'redirect_by_request_uri' );

The above examples both hook into the template_redirect function, do some checks and then make a safe 301 redirect at the right moment in the WordPress process. They both give the same result, but the best option depends on whether you want to delete the old posts.