inserting or updating a query parameter with .htaccess

Viewed 90

I want every access to my page situated at www.mysite.com/nouveauSite/shop.html to be redirected to the same url with locale=fr added to the query string.

I can see 3 types of requests:

  1. Url with no query string: /nouveauSite/shop.html should be rewritten to /nouveauSite/shop.html?locale=fr
  2. Urls with a query string, but no locale parameter: /nouveauSite/shop.html?foo=3 should be rewritten to /nouveauSite/shop.html?locale=fr?foo=3
  3. Urls with a query string containing the locale parameter set to something other than fr: /nouveauSite/shop.html?foo=3&locale=en should be rewritten to /nouveauSite/shop.html?locale=fr&foo=3

Right now I only have number 2 working. I am using this rule:

RewriteCond %{QUERY_STRING} !locale=
RewriteRule ^shop.html     /nouveauSite/shop.html?locale=fr [R,L,QSA]

I thought this rule:

RewriteCond %{REQUEST_URI} ^/nouveauSite/shop.html
RewriteRule ^shop.html     /nouveauSite/shop.html?locale=fr [R,L]

would fix number 1, but it does not seem to work.

I don't know what to do for number 3.

1 Answers

You will need 2 redirect rules in your .htaccess for this:

  1. Check if locale= query parameter doesn't exist in query string, then simple add locale=fr with QSA flag to preserve original query string.
  2. A bit more involved rule to check if locale= query parameter exists with anything other than fr value then we'll have to replace it with locale=fr

You can have these 2 redirect rules:

RewriteEngine On

# rule #1 when locale= doesn't exist
RewriteCond %{REQUEST_URI} ^/nouveauSite/shop\.html$ [NC]
RewriteCond %{QUERY_STRING} !(?:^|&)locale= [NC]
RewriteRule . %{REQUEST_URI}?locale=fr [R=302,L,QSA]

# rule #2 when locale= exists with anything other than fr
RewriteCond %{REQUEST_URI} ^/nouveauSite/shop\.html$ [NC]
RewriteCond %{QUERY_STRING} ^(.*&)?locale=(?!fr(?:&|$))[^&]*(?:&(.*))?$ [NC]
RewriteRule ^ %{REQUEST_URI}?%1locale=fr%2 [R=302,L]

I have kept R=302 in these rules for testing purpose and you should change them to R=301 afterwards to make it permanent redirect.

Test Results with above rules

curl -I 'localhost/nouveauSite/shop.html'
HTTP/1.1 302 Found
Date: Tue, 03 Nov 2020 05:38:12 GMT
Server: Apache/2.4.46 (Unix) OpenSSL/1.1.1h PHP/7.4.11
Location: http://localhost/nouveauSite/shop.html?locale=fr
Content-Type: text/html; charset=iso-8859-1


curl -I 'localhost/nouveauSite/shop.html?foo=3'
HTTP/1.1 302 Found
Date: Tue, 03 Nov 2020 05:38:40 GMT
Server: Apache/2.4.46 (Unix) OpenSSL/1.1.1h PHP/7.4.11
Location: http://localhost/nouveauSite/shop.html?locale=fr&foo=3
Content-Type: text/html; charset=iso-8859-1


curl -I 'localhost/nouveauSite/shop.html?foo=3&locale=en'
HTTP/1.1 302 Found
Date: Tue, 03 Nov 2020 05:40:22 GMT
Server: Apache/2.4.46 (Unix) OpenSSL/1.1.1h PHP/7.4.11
Location: http://localhost/nouveauSite/shop.html?foo=3&locale=fr
Content-Type: text/html; charset=iso-8859-1
Related