skip to Main Content

I have been trying to perform this redirect without success so far. I have a WordPress site, and my URLs currently follow this pattern:

https://example.com/slug-title/

And I need to change them to this pattern:

https://example.com/post-category/slug-title/

I would like to find a way to do this dynamically without harming my SEO. I tried creating this code in my functions.php, but it’s not working:

Is there another way to perform this redirect? I do not wish to use a plugin for this action.

I appreciate any help and ideas.

add_action('template_redirect', 'custom_category_redirect');
function custom_category_redirect() {
    if (is_single() && !is_admin()) {
        global $post;
        $categories = get_the_category($post->ID);
        if (!empty($categories)) {
            $category_slug = $categories[0]->slug; // Gets the slug of the first category of the post
            $current_url = $_SERVER['REQUEST_URI']; // Gets the current URL
            $current_slug = basename(get_permalink($post->ID)); // Gets the current slug
            $new_url = home_url("/$category_slug/$current_slug/"); // Target URL with the category slug
            if (home_url(add_query_arg(array())) !== $new_url) {
                wp_redirect($new_url, 301); // Permanently redirects
                exit;
            }
        }
    }
}

2

Answers


  1. Instead of this

    add_action('template_redirect', 'custom_category_redirect');
    

    Use this

    add_action('wp', 'custom_category_redirect');
    

    template_redirect happens before the headers are sent and causing your redirect to occur too late, The wp hook called after WordPress has finished loading but before any headers are sent.

    Note: I prefer .htaccess redirect and permalink changes. It is easier, faster and use less resources.You can update permalink to support your new url and add all old url as redirect (not rewrite) in your .htaccess If you have installed plugins like yoast, after updating permalinks they add required redirect to .htaccess

    Login or Signup to reply.
  2. Your approach seems reasonable, but there might be a few issues causing it not to work as expected. Let’s try to debug and refine it:

    Hooking: The template_redirect action hook should work fine for this purpose, but make sure it’s being triggered correctly.

    Getting the Category: Ensure that $categories is not empty and that you’re correctly retrieving the category slug. If a post has multiple categories, your code currently only considers the first one. If that’s the desired behavior, it’s fine.

    URL Handling: Your handling of URLs seems correct, but it’s always a good idea to debug and print out variables to ensure they contain the expected values.

    Redirecting: Your redirect logic seems correct, but we might need to ensure that it’s being triggered at the right time and in the right context.

    Here’s a refined version of your code with some debug information included:

    add_action('template_redirect', 'custom_category_redirect');
    function custom_category_redirect() {
        if (is_single() && !is_admin()) {
            global $post;
            $categories = get_the_category($post->ID);
            if (!empty($categories)) {
                $category_slug = $categories[0]->slug; // Gets the slug of the first category of the post
                $current_url = $_SERVER['REQUEST_URI']; // Gets the current URL
                $current_slug = basename(get_permalink($post->ID)); // Gets the current slug
                $new_url = home_url("/$category_slug/$current_slug/"); // Target URL with the category slug
                
                // Debugging - print out variables
                // echo "Current URL: $current_url<br>";
                // echo "Current Slug: $current_slug<br>";
                // echo "Category Slug: $category_slug<br>";
                // echo "New URL: $new_url<br>";
                
                if (home_url(add_query_arg(array())) !== $new_url) {
                    wp_redirect($new_url, 301); // Permanently redirects
                    exit;
                }
            }
        }
    }
    

    Ensure that:

    Your WordPress permalinks are set up properly.
    There’s no conflicting code or plugin interfering with the redirect.
    You might need to clear your browser cache or try in an incognito window to ensure you’re not seeing cached responses.
    If this still doesn’t work, you might need to dig deeper into debugging, perhaps by using var_dump() or error_log() to understand how the variables are behaving and where the issue lies.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search