tinganho / node-accept-language

BCP47 language negotiation
MIT License
85 stars 15 forks source link

Latest version always returns less specific language #26

Closed dlebech closed 7 years ago

dlebech commented 7 years ago

It looks like the library returns the least-specific version of a language after the discussion in #23 and the latest update. Is this expected behavior?

> const acceptLanguage = require('accept-language')
> acceptLanguage.languages(['en', 'en-US'])
> acceptLanguage.get('en-US')
'en'

I was expecting a match on en-US here. Reversing the order of 'en' and 'en-US' produces the correct result. Is this expected behavior and do we thus need to be careful with the ordering of the specific languages?

tinganho commented 7 years ago

It does the checking:

  1. en-US == en ? no
  2. en == en ? yes
  3. en-US == en-US ? yes

And then it adds matched ones to a list. And it takes the first one in the matched list. But I do agree it should match based on the most specific as possible here.

tinganho commented 7 years ago

Just a question, what do you expect this should return?

> const acceptLanguage = require('accept-language')
> acceptLanguage.languages(['en', 'en-US'])
> acceptLanguage.get('en, en-US')
?
tinganho commented 7 years ago

@micky2be maybe have some inputs as well?

dlebech commented 7 years ago

@tinganho Thanks for your explanation. For your example, I would expect en because it's the first one on the accept list. I don't know why a browser would report en,en-US in that order though (my own browser reports en-US,en;q=0.8,da;q=0.6,sv;q=0.4), but I also admit that I don't know enough about how the accept languages work in general, nor have I fully read the RFC for this :-)

Basically, my assumption was that if there's a specific match early in the accept string, like en-US in my case, then that would always match first, no matter the order of the languages given to languages([...]).

micky2be commented 7 years ago

From the first issue it should return ’en-US’ obviously. It should match the higher choice first. Don't remember the code but my guess is that it matches both and return the first in the list.

If you have ’en’ and ’en-US’ in both accepted language and requested language, the priority is used. If equal priority, the order in the list takes over (closer to index 0 wins)

tinganho commented 7 years ago

This issue should be fixed now.