skip to Main Content

I am trying to use htaccess to make multi-language site and to translate something like site.com/de/path to site.com/path and set a cookie for language to "de" in this case. currently i have this solution:

RewriteCond %{HTTP_COOKIE}::%{REQUEST_URI} !language=(en|de|fr|ar).*::/1/.*
   RewriteRule ^(en|de|fr|ar)/(.*)$                         /$1/$2 [R,L,CO=language:$1:site.com:2678400:/]
 RewriteRule ^(en|de|fr|ar)/(.*)$                           /$2

But this is doing a redirect that i am willing to avoid for less traffic and more speed and also some crawlers might not like that.

So is there an other way to set this cookie on first load without redirecting?

Also i am curious why htaccess does not set the cookie directly on first load?

Note just setting the cookie without redirect as in the code below will make the cookie appears in php at second load of site:

RewriteRule ^(en|de|fr|ar)/(.*)$                         /$1/$2 [CO=language:$1:site.com:2678400:/]

Also preferably stick with cookies as using request parameters to send the language value to script might mess other links with parameters.

Further using env variable as an option seems to me as far fetched and not sure how it would affect the servers and its other systems.

2

Answers


  1. Sometimes simple descriptions can be misleading. Really, there is no such thing as "setting a cookie"; there is :

    1. The server sending a Set-Cookie: ... header in the response to the browser, which it then stores
    2. The browser finding a value in its store and sending a Cookie: ... header in the next request to the server

    Neither of those things allow Apache (on the server) to send new cookie information to PHP (also on the server). The only cookies PHP will see are those sent by the browser; the first time a user visits your site, there will not be any.

    So, you need to do something other than sending a Set-Cookie header, e.g.

    • Have Apache set an environment variable, which is a communication between different processes on the server.
    • Don’t remove the language from the URL in the Apache configuration, instead detecting it in PHP, where you can both set the current language and send a cookie to the browser.
    Login or Signup to reply.
  2. In addition to @IMSoP’s answer that explains why.

    RewriteCond %{HTTP_COOKIE}::%{REQUEST_URI} !language=(en|de|fr|ar).*::/1/.*
    RewriteRule ^(en|de|fr|ar)/(.*)$ /$1/$2 [R,L,CO=language:$1:site.com:2678400:/]
    

    …and also some crawlers might not like that.

    SE crawlers generally do not send cookies at all, so depending on a cookie to hold the language code is going to be problematic. The above rule (that looks at the cookie value and redirects to "correct" the cookie if it does not match the language code in the URL-path) will break SE crawlers (and any user that blocks or rejects cookies) – so the site will not be indexed.

    The only reason (if at all) to set a language cookie should be to persist the user’s chosen language between sessions. eg. On first visit and the language code prefix is missing from the URL?

    RewriteRule ^(en|de|fr|ar)/(.*)$ /$2
    

    You are removing the language code prefix with an internal rewrite – so you are not actually changing the URL. I’m assuming this is necessary in order to be able to serve "static files"? eg. /en/path/to/file.php is internally rewritten to /path/to/file.php where the file actually resides? (Otherwise, I see no reason for this rule.)

    There doesn’t seem to be a need for cookies, environment variables or "language" URL parameters at all here since the language code can be read directly from the URL-path.

    For example, in PHP, parse the $_SERVER['REQUEST_URI'] superglobal:

    <?php
    preg_match('@^/(en|de|fr|ar)/@',$_SERVER['REQUEST_URI'],$matches);
    $langCode = $matches[1] ?? null;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search