Jose A.
Jose A.

Reputation: 125

Apache mod_rewrite accept language subdomain redirection

i have a multilingual site with 3 languages and i'm using the following rules to redirect requests to the right version of the website based in browser accept language.

#swedish
RewriteCond %{HTTP:Accept-Language} ^sv.*$ [NC]
RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteCond %{QUERY_STRING} !(^q\=) [NC]
RewriteRule ^(.*)$ /sv [L,R=301]

#norwegian bokmal
RewriteCond %{HTTP:Accept-Language} ^nb.*$ [NC]
RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteCond %{QUERY_STRING} !(^q\=) [NC]
RewriteRule ^(.*)$ /nb [L,R=301]

#norwegian
RewriteCond %{HTTP:Accept-Language} ^no.*$ [NC]
RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteCond %{QUERY_STRING} !(^q\=) [NC]
RewriteRule ^(.*)$ /nb [L,R=301]

#all others go to english
RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteCond %{QUERY_STRING} !(^q\=) [NC]
RewriteRule ^(.*)$ /en [L,R=301]

I need to upgrade this rules to do the same redirections keeping subdomains too

Example for a norwegian request:
www.domain.com/subdomain -> www.domain.com/nb/subdomain

How can i achieve this?

I have thank @faa for helping me out with the current rules.

Upvotes: 2

Views: 6731

Answers (2)

Felipe Alameda A
Felipe Alameda A

Reputation: 11799

UPDATE

Question Description

Regarding the pages vs subdomains issue in your comments, in this specific case is irrelevant. The fact is the incoming URL in your question is: www.domain.com/subdomain and, except for the name, /subdomain is clearly a page.

A real subdomain is indeed a domain that is part of another domain and the URL format that holds it, is something like subdomain.domain.com, so there was no confusion on my part.

What it is not clear enough, is how the redirection will be handled. According to your question, but replacing "subdomain" with the whole path, here are some examples:

  1. www.domain.com/ should go to www.domain.com/LangCode/, (previous working redirection)

  2. www.domain.com/page should go to www.domain.com/LangCode/page

  3. www.domain.com/page1/page2/page3/etc/ should go to www.domain.com/LangCode/page1/page2/page3/etc. This possibility is not in the question, but eventually could be neded.

In those cases, the pages in the incoming and redirected URLs should have the same name, but, although in the incoming URL do not have to exist, in the redirected URL the pages MUST exist and so a loading default script (index.php or index.html, for example) to handle the request.

Which means, there has to be a script in each page subject to redirection. I would say at least 2 for each language.

As far a I understand, that's what the question and complementary comments indicate, but it seems it is not a practical approach.

Suggested Solution

A better approach could be a single script at the root folder that handles all requests. This is an idea that can be better described with examples:

  1. www.domain.com/ always showing in the browser's address bar but going internally to www.domain.com/lang_handler.php?lang=sv or

  2. www.domain.com/page1/ always showing in the browser's address bar but going internally to www.domain.com/lang_handler.php?lang=sv&target_page1=page1

This can be achieved in .htaccess with mod_rewrite directives. Here is an example:

RewriteEngine On
RewriteBase  /

# Set managed languages here, except default (en)
RewriteCond %{HTTP:Accept-Language} ^(sv|ne|no).*$ [NC]

# Replace the names of the script and the parameters in the next 2 lines
RewriteCond %{REQUEST_URI} !lang_handler\.php              [NC]
RewriteRule ^([^/]+)?/?$  lang_handler.php?lang=%1&target_page1=$1  [L,QSA]

# If no match, set English
# Replace the names of the script and the parameters in the next 2 lines
RewriteCond %{REQUEST_URI}  !lang_handler\.php             [NC]
RewriteRule ^([^/]+)?/?$  lang_handler.php?lang=en&target_page1=$1  [L,QSA]

The above rule set maps silently

http://www.domain.com/ or http://www.domain.com/page1

To

http://www.domain.com/lang_handler.php?lang=LangCode&target_page1=page1

Where LangCode is sv ne no or en by default.

This example only works for 1 page or no page. Any number of pages can be handled though, but the rules have to be modified accordingly. More parameters and regex groups have to be added to the RewriteRules.

Upvotes: 2

Ankit
Ankit

Reputation: 3183

$1 should do the trick.

RewriteCond %{HTTP:Accept-Language} ^no.*$ [NC]
RewriteCond %{REQUEST_URI} ^/$ [NC]
RewriteCond %{QUERY_STRING} !(^q\=) [NC]
RewriteRule ^(.*)$ /nb/$1 [L,R=301]

Upvotes: 0

Related Questions