Search code examples
.htaccessmod-rewrite

HTACCESS: Rewrite a Previously Rewritten URL Causes Error


not sure what my problem is, but I insert one rewrite into my htaccess file and the whole thing breaks. I used an htaccess tester and it says the rule works fine.

For some reason Google indexed the php file that I normally rewrite URLs to. So I need to take the .php page that displays and send it to the proper rewritten URL.

Here is the rule:

RewriteRule ^products/Automotive-Transmission-Torque-Converters-results.php$ /Search-Results [QSA,R=301,L]

The only thing I can think that would be causing the problem, is that I use this URL in another rewrite later on in my code.

Here is the second rewrite later on in the file:

RewriteRule ^Search-Results/?$ /products/Automotive-Transmission-Torque-Converters-results.php [QSA]

I hope I've identified the problem correctly. But again, I put the first rewrite rule into my htaccess and the the regular page doesn't show, the browser says there is an error on the page. Yet, htaccess testers say the rule works fine. Hence my suspicion.


Solution

  • RewriteRule ^products/Automotive-Transmission-Torque-Converters-results.php$ /Search-Results [QSA,R=301,L]
    
    RewriteRule ^Search-Results/?$ /products/Automotive-Transmission-Torque-Converters-results.php [QSA]
    

    Yes, these two directives used together will result in a redirect-loop (something that online testers don't appear to check for). The problem is that the first rule will trigger an external redirect after the second rule has rewritten the URL (when the rewrite engine starts over - in .htaccess).

    The solution is to make sure the first rule (the external redirect) only triggers on direct requests from the client and not requests that have been internally rewritten.

    We can check for direct HTTP requests by checking against the REDIRECT_STATUS environment variable, which is empty on the initial request and set to "200" (as in 200 OK HTTP status) after the first successful rewrite.

    For example:

    # Redirect direct request for PHP file to canonical URL
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ^products/Automotive-Transmission-Torque-Converters-results\.php$ /Search-Results [R=301,L]
    
    # Internally rewrite the canonical URL
    RewriteRule ^Search-Results/?$ /products/Automotive-Transmission-Torque-Converters-results.php [L]
    

    Note that I have removed the QSA from both rules, since it's not required here (the query string is appended by default). And I've included the L flag on the second rule. Also, don't forget to backslash escape the literal dot in the RewriteRule pattern.

    Test first with 302 (temporary) redirect to avoid potential caching issues and make sure your browser cached is cleared before testing.


    For some reason Google indexed the php file that I normally rewrite URLs to.

    However, you need to try and identify how Google managed to find the PHP file/URL in the first place. If this is the a result of an incorrect internal link on your site then it needs to be fixed.