Do language based redirects take into account browser's language?

I have the following rules in my _redirects file:

/                               /en/                            302  Language=en
/                               /fr/                            302 

Whenever I access the root (/), the redirection doesn’t take into account of browser’s language (Accept-Language header):

The doc only mentions the cookie approach to be overriden by Javascript but doesn’t talk about Accept-Language header:

Netlify supports GeoIP and language-based redirects directly from our CDN nodes.

This is ideal for large multi-regional sites where you want to send people to the right location based on their location or browser language.

Both the language and the country can be specified in a cookie as well ( nf_lang and nf_country respectively), so you can easily override the default behavior with JavaScript

My site is a pretty simple landing page so I don’t want to use cookies. Could you tell me how the default behavior of this kind of redirect works? How Netlify detects user language?

Thanks in advance,


That redirect is working for me:

Can you tell me how you are reproducing this error, if it still occurs? Also, if so if you could paste the value of the X-NF-Request-ID HTTP response header those are viciously hard to retype and we can correlate them to individual requests and CDN servers to help us track things down. I did manage to get yours retyped and see your server, but cannot reproduce directly on it either, using your headers, so I suspect it may have been something in cache that was fixed by some cache clearing we did yesterday.

Hi @futuregerald,

Thanks for your check. Unfortunately, the error is still persist. To reproduce it, I do nothing in particular, just type the address in a browser. You can even produce it with a curl command like this:

curl -H 'Accept-Language: en-US,en;q=0.5' -L -v -s 1> /dev/null

and its output (in my computer, based in Paris, France):

* Rebuilt URL to:
*   Trying
* Connected to ( port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [222 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [102 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2570 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [300 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [37 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject:
*  start date: Jul 19 01:29:38 2019 GMT
*  expire date: Oct 17 01:29:38 2019 GMT
*  subjectAltName: host "" matched cert's ""
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f837b006600)
> GET / HTTP/2
> Host:
> User-Agent: curl/7.54.0
> Accept: */*
> Accept-Language: en-US,en;q=0.5
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 302
< cache-control: public, max-age=0, must-revalidate
< content-length: 20
< content-type: text/plain; charset=utf-8
< date: Fri, 09 Aug 2019 05:40:40 GMT
< location: /fr/
< age: 266477
< server: Netlify
< x-nf-request-id: de5a6584-b422-4c83-9209-91b71677ec39-6055060
* Ignoring the response-body
{ [20 bytes data]
* Connection #0 to host left intact
* Issue another request to this URL: ''
* Found bundle for host 0x7f837a516bf0 [can multiplex]
* Re-using existing connection! (#0) with host
* Connected to ( port 443 (#0)
* Using Stream ID: 3 (easy handle 0x7f837b006600)
> GET /fr/ HTTP/2
> Host:
> User-Agent: curl/7.54.0
> Accept: */*
> Accept-Language: en-US,en;q=0.5
< HTTP/2 200
< cache-control: public, max-age=0, must-revalidate
< content-type: text/html; charset=UTF-8
< date: Fri, 09 Aug 2019 20:31:36 GMT
< etag: "9141d92a19fb4522b219e2cbb6649bda-ssl"
< strict-transport-security: max-age=31536000
< age: 213021
< content-length: 1353472
< server: Netlify
< x-nf-request-id: de5a6584-b422-4c83-9209-91b71677ec39-6055083
{ [16384 bytes data]
* Connection #0 to host left intact

Its Netlify ID is: de5a6584-b422-4c83-9209-91b71677ec39-6055060

Other test with my browser: de5a6584-b422-4c83-9209-91b71677ec39-6101910

Hope it helps.

Thanks for those details and sorry to be slow to get back to you! Just after clearing the cache, I see that we get perfect redirects for your example curl from each CDN node, but I can see that it seems to diverge over time so that sometimes the redirect to /fr/* is happening instead.

That seems like a bug in our caching of redirects, and I’m not certain how soon we’ll have a fix. In the meantime, you may want to try deploying your “primary” content in the main folder so you don’t need a redirect for it - instead only redirecting /fr since /en/* actually lives in / instead.

I understand that isn’t optimal, but it’s my best suggestion for getting things working at present.

Thank @fool for the workaround. I will have a look into it further.

Just out of curiosity, is there any way that I can get informed about the issue status if the Netlify team fix it in the future? Some kind of change logs / release notes?

Many thanks,

1 Like

hi there, I don’t have a timeline for this per se, but, we have this thread mentioned in the issue for this concern and will post an update here when there is any news :muscle:

1 Like

We would also really need this.
Actually we expected this to work, after reading the manuals form:

We are trying to do this:
/ /de/ 301 Language=de
/ /es/ 301 Language=es
/ /en/ 301

What we get is an redirect to /en, always.
Also in the .toml syntax this did not work.

Is there any workaround?