sergiodxa / remix-i18next

The easiest way to translate your Remix apps
https://sergiodxa.github.io/remix-i18next/
MIT License
616 stars 44 forks source link

Root match doesn't exist #207

Closed jansedlon closed 2 months ago

jansedlon commented 3 months ago

Describe the bug

Hello Sergio.

From time to time we get an error report in Sentry in remix-i18next saying that o(...).at is not a function. It occurs in this line of code

const locale = useLocale();

The at function is used in here

image

I have no idea how it can happen but it's probably safe to say that root match sometimes cannot exist?

Your Example Website or App

none

Steps to Reproduce the Bug or Issue

none

Expected behavior

Root match should exist but i guess sometimes it doesn't. It always happens in Instagram or Facebook in-app browser. (That's a whole another story, the browsers are doing what they please).

Screenshots or Videos

image

Platform

Additional context

No response

jansedlon commented 2 months ago

@sergiodxa Correct me if i'm wrong but i think that the package accept-language-parser that you copied the code recently from is not 100% correct according to spec.

Spec

There are actually two valid variants of accept-language. More on that here spec.

In simple terms, one allows whitespaces and the other doesn't.

accept-language-parser behavior

The accept-language-parser does not support whitespaces in the header. Which means that

parser.parse('en-GB;q=0.8')

results in

[ { code: 'en', script: null, region: 'GB', quality: 0.8 } ]

This one's correct. However when i add a whitespace

parser.parse('en-GB; q=0.8')

which is i guess correct according to spec, results in

[
  { code: 'en', script: null, region: 'GB', quality: 1 },
  { code: 'q', script: null, region: undefined, quality: 1 }
]

Which is not correct because q is not a valid language

Runtime behavior

When i received a request which has a whitespace in Accept-Language header, it throws an exception. I'm not entirely sure where exactly, but i suspect this https://github.com/sergiodxa/remix-i18next/blob/73d3765756f4f4fc5515a0222f517be547825a2a/src/lib/get-client-locales.ts#L32

I've noticed that most of the requests that fail come from bots. The rest of the requests which do not appear to come from bots come from quite old browsers (chrome 75, etc).

Proof

It's not a proof per-se but i have tried validating the whitespace variant in a rust library accept-language and it processed the whitespaces correctly. Also when I looked at accept-language PHP library, it also tests against whitespaces

https://github.com/kudashevs/accept-language/blob/1cf6c2fce6618314462df3d6f39c85b61abaa17e/tests/Unit/AcceptLanguageTest.php#L550-L556