2

I made some changes to the files on a website and now Search Console is showing me 404 errors for some URLs.

The normal setup, which works fine is like this:

  • the user-friendly URL

    mywebsite.com/modeles-voiture/Volvo/XC60
    

is rewritten to get to the PHP script as:

 RewriteCond %{REQUEST_URI} ^/?modeles-voiture [NC]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule \/([A-Z][\-A-Za-z]+)\/([\-A-Za-z0-9\.]+$) /models.php?brand=$1&model=$2 [L]

Now, I do have some old URLs out there, that are generating the 404 errors and that look like:

mywebsite.com/modeles.php?brand=Volvo&model=XC60

So, I came up with the following redirect to send them to the right place.

This first step would redirect the old URLs to the new, user-friendly ones:

RewriteCond %{REQUEST_URI} \/modeles\.php [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule brand=([A-Z][\-A-Za-z]+)&model=([\-A-Za-z0-9\.]+$) http://www.soeezauto.com/modeles-voiture/$1/$2 [R=301,L]

Then, the existing code ( below ), would do its regular job of sending over to the proper PHP script.

So ( just repeating what I stated up on the top ):

 RewriteCond %{REQUEST_URI} ^/?modeles-voiture [NC]
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule \/([A-Z][\-A-Za-z]+)\/([\-A-Za-z0-9\.]+$) /models.php?brand=$1&model=$2 [L]

My this is not working. Still getting a 404 error.

I did test all the individual regexps ( at regex101.com ) and they seem to do what they are supposed to.

I may just have made the wrong assumption concerning the chaining, but in that case, what is the solution to this?

1 Answer 1

2
RewriteCond %{REQUEST_URI} \/modeles\.php [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule brand=([A-Z][\-A-Za-z]+)&model=([\-A-Za-z0-9\.]+$) http://www.soeezauto.com/modeles-voiture/$1/$2 [R=301,L]

You can't match the query string with the RewriteRule pattern. The RewriteRule only matches against the URL-path (less the query string). To match the query string you need to use a RewriteCond directive and check against the QUERY_STRING server variable.

It is also more efficient to match the URL-path in the RewriteRule, rather than using a condition to match against REQUEST_URI (where possible).

Try something like:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} ^brand=([A-Z][-A-Za-z]+)&model=([-A-Za-z0-9.]+)$
RewriteRule ^modeles\.php http://www.example.com/modeles-voiture/%1/%2? [R=301,L]

This matches the exact query string, eg. brand=Volvo&model=XC60 - if there are other URL params then this will not match.

EDIT: The ? on the end of the substitution effectively removes the query string from the redirected URL. Alternatively, on Apache 2.4, you can use the QSD (Query String Discard) flag.

You don't need to escape slashes in Apache config regex. (Apache regex does not use slash delimiters.) In a regex character class you also don't need to escape literal dots, or hyphens if they occur at the start or end of the character class.

The RewriteRule substitution uses %1 and %2 (as opposed to $1, etc) as a backreference to the last captured group(s) in the RewriteCond directive.

3
  • Hi @w3dk. Thanks. This works partially. It stops generating the 404 error and send to the correct page. Where it falls short is that it appends the query string to the user-friendly URL, which is not desired. I tried adding a question mark at the end of the RewriteRule, as I read somewhere that this would prevent the query string from being appended, but that did not work.
    – BernardA
    Commented May 14, 2016 at 19:34
  • my previous comment was based upon a test I made on local installation. I've tested now on my web host and it seems to work. This may just be a server configuration issue and not your code. I will check further and let you know.
    – BernardA
    Commented May 14, 2016 at 20:37
  • "adding a question mark at the end of the RewriteRule" - Yes, you will need to do this to remove the query string from the redirected URL - sorry, missed that (I've added this to my answer). However, you will need to make sure you've cleared your browser cache before testing as the previous 301 redirect will have been cached by the browser. (It is sometimes easier to test with 302 Temporary redirects for this reason and only change to 301 when you are sure it's working OK.)
    – MrWhite
    Commented May 14, 2016 at 20:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.