skip to Main Content

I want to redirect each link with a query string to a specific address by appending the string. I have the following in my WordPress .htaccess:

RewriteEngine On
RewriteCond %{QUERY_STRING} catid=([0-9]+) [NC]
RewriteRule (.*) catid%1? [R=301,L]

When a user hits example.com/?catid=10, they are successfully redirected to example.com/catid10, which is what I want.

However, when they go a directory deeper (example.com/category/?catid=10), they are not redirected to example.com/category/catid10.

I have been reading manuals but can’t find the answer.

Edit

If this is helpful, this is what WordPress has defined in my htaccess:

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

2

Answers


  1. You just need to add the captured group from (.*) to your redirect target using $1. I’d break it up into a few rules so that you don’t get duplicated slashes. Rather then ending your rewrite targets with a question mark, I would add the QSD (query string discard) flag to the rule. I would also add starts with (^) and ends with ($) to rewrite rule so you always match the whole thing. I also like to start my rules with an optional slash (/?) so that the rules can be used in both .htaccess and apache conf.

    RewriteEngine On
    
    # Home URL with catid query string
    RewriteCond %{QUERY_STRING} catid=([0-9]+) [NC]
    RewriteRule ^/?$ /catid%1 [R=301,L,QSD]
    
    # Deep URL ending in slash with a catid query string
    RewriteCond %{QUERY_STRING} catid=([0-9]+) [NC]
    RewriteRule ^/?(.*)/$ /$1/catid%1 [R=301,L,QSD]
    
    # Deep URL not ending in slash with a cadid query string
    RewriteCond %{QUERY_STRING} catid=([0-9]+) [NC]
    RewriteRule ^/?(.*)$ /$1/catid%1 [R=301,L,QSD]
    
    Login or Signup to reply.
  2. Providing RewriteBase / is already defined (which it normally is with WordPress and must be if your existing redirect is working) then you can do it like the following with a single rule:

    RewriteCond %{QUERY_STRING} (?:^|&)catid=(d+) [NC]
    RewriteRule (.*?)/?$ $1/catid%1 [QSD,R=301,L]
    

    The capturing group (.*?) is non-greedy so does not consume the optional trailing slash that follows.

    Requests for the document root do not require RewriteBase, but all "deeper" URLs do, since the resulting substitution string will otherwise be a relative URL.

    The non-capturing (?:^|&) prefix on the CondPattern ensures that it only matches the URL parameter name catid and not foocatid etc.

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