Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fallback language not found if $locale is not listed in dictionary #137

Closed
Egnus opened this issue Mar 27, 2021 · 7 comments · Fixed by #138
Closed

Fallback language not found if $locale is not listed in dictionary #137

Egnus opened this issue Mar 27, 2021 · 7 comments · Fixed by #138

Comments

@Egnus
Copy link

Egnus commented Mar 27, 2021

Describe the bug
I have a website that can handle hundreds of languages decided by their authors. some support pages are maintained by us and by a small supported amount of languages.

Currently the page locale is selected based on whatever the user currently is having or the author has selected for that content, this is likely to be not covered by the dictionaries.

For instance, we support en-GB language and also this one is the fallback language if the user has selected one without dictionary.
But when the user selects en-AU. Then i18n fails and none is loaded.

Is all languages to be expected to be part of dictionaries?

In the console log I get the following message as example (and many more with the same):

[svelte-i18n] The message "page.help.title" was not found in "en", "en-AU", "en", "en-GB".
but the dictionary works and the language is loaded:

{
    "en-GB": {
        "page": {
            "help": {
                "title": "Need some help?",
               ...
            },
           ...
        }
    },   
    "zh-CN": {...},
    ...  // IMPORTANT: en-AU is NOT a dictionary supported and is not in this list
}

As soon as i switch the language by clicking on en-GB all works again, and also if the language is covered by the dictionaries (ex: zh-CN ) even if some translations for that language are missing.

Does all the languages has to be included as dictionaries? The fallback method should always work I believe

How do I load dictionaries:

  register('en-GB', () => import('..../en-GB.json'));
  register('zh-CN', () => import('..../zh-CN.json'));
  ...  // IMPORTANT: en-AU is NOT a dictionary supported and is not registered here

  init({
    fallbackLocale: 'en-GB',
    initialLocale: 'en-GB',
  });

How locale is set by user actions:

$: if ($lang !== undefined) { // Lang is reactive and selected by the options of the page, NOT the locales available
    const l = $lang;
    setLang(l);          // some local cookies for usage to handle reload
    const parsedLang = isChineseSpecific(l) ? 'zh-CN' : l; // Chinese fix to force simplified instead of traditional chinese
    if ($locale !== parsedLang) {
      $locale = parsedLang; // if users is on `en-AU`, support pages should use still the fallback `en-GB`, but it fails.
    }
  }

Logs

main.js:1147 [svelte-i18n] The message "page.help.title" was not found in "en", "en-AU", "en", "en-GB".
main.js:1147 [svelte-i18n] The message "page.help.subtitle" was not found in "en", "en-AU", "en", "en-GB".
main.js:1147 [svelte-i18n] The message "page.help.text" was not found in "en", "en-AU", "en", "en-GB".

Stacktrace for the first line

main.js:1147 [svelte-i18n] The message "page.help.title" was not found in "en", "en-AU", "en", "en-GB".

[svelte-i18n] The message "page.help.title" was not found in "en", "en-AU", "en", "en-GB".
console. @ main.js:1147
B @ main.js:10229
instance @ help.js:116
init @ main.js:910
Help @ help.js:150
create_default_slot @ main.js:2380
create_slot @ main.js:110
create_fragment @ main.js:1180
init @ main.js:925
Noop @ main.js:1247
create_each_block$1 @ main.js:2478
update_keyed_each @ main.js:731
update @ main.js:2175
update @ main.js:2591
update @ main.js:420
flush @ main.js:388
Promise.then (async)
schedule_update @ main.js:363
make_dirty @ main.js:880
(anonymous) @ main.js:916
onComponentLoaded @ main.js:2682
Promise.then (async)
setComponent @ main.js:2702
$$self.$$.update @ main.js:2797
update @ main.js:416
flush @ main.js:388
Promise.then (async)
schedule_update @ main.js:363
make_dirty @ main.js:880
(anonymous) @ main.js:916
callback @ main.js:3126
updatePage @ main.js:2897
async function (async)
updatePage @ main.js:2894
updatePage @ main.js:3124
goto @ main.js:1931
onTutorial @ index3.js:265
(anonymous) @ main.js:333
(anonymous) @ main.js:332
showTutorial @ WelcomePage.js:18643
(anonymous) @ main.js:350
bubble @ main.js:350
click_handler_1 @ WelcomePage.js:5582

To Reproduce

  1. Create an svelte app with 1 language i18n only and set it as fallback
  2. force locale to any other thing
  3. Check that the variables are not loading the fallback

Expected behavior
Whichever string you add as locale, if it does not exist, fallback should be used instead.

Information about your project:

Built and tested with:

  • Rollup
  • Svelte Preprocess
  • svelte-i18n v.3.3.7
  • Mac Catalina
  • Latest Chrome, Firefox, Safari.
@kaisermann
Copy link
Owner

Hey @Egnus 👋 Thanks for the detailed issue!

That's a funny one. I've built the fallback mechanism thinking of "generic" fallbacks, such as "en", "pt", "es", not more specific ones like "en-GB".

Will fix it soon!

@Egnus
Copy link
Author

Egnus commented Mar 27, 2021

Oh, well, we implemented this on this way because we have to support languages that have big differences between the zones.
For instance, Spanish from Spain has many keywords that differs a lot from Spanish from Mexico.
And therefore the end users might feel confused or even unhappy for the app not supporting their native language.
This app is based on culture, general knowledge and art so whatever thing we can do to encourage the users to stay it is important for us.

Thank you for your response. Meanwhile I will drive manually languages to en-GB when is not in the dictionary but I really think that this feature should be by default in the app.

@kaisermann
Copy link
Owner

Understood! In that example, the initial idea, at least for me was to use the es as a base and overwrite whatever is needed in the es-AR and es-ES dictionaries.

Thank you for your response. Meanwhile, I will drive manually languages to en-GB when is not in the dictionary but I really think that this feature should be by default in the app.

I agree with you there. PR #138

@Egnus
Copy link
Author

Egnus commented Mar 27, 2021

Oh right, I clearly didn't think on that and it makes sense. I will move the project toward that thanks.
But still, I think it might fails also if the user set the locale to ru-RU and I have no support at all with Russian.
The English fallback might not be loaded. But perhaps if I register it en as language and fallback it will work.
From what I see in your fix it seems that the reason was only the dash in fallback and not the lack of support to any possible string as possible language by the end user.

@Egnus
Copy link
Author

Egnus commented Mar 27, 2021

Nice, I cloned the project, built it, changed dist with my dist in node_modules and it works perfect for my case.

@kaisermann
Copy link
Owner

@Egnus Yeah, the fallback logic didn't allow to fallback to a more specific locale (en-GB) from a more generic one (en). en-AU => en => en-GB was not possible.

@kaisermann
Copy link
Owner

Release in 3.3.8.

I think this change makes sense, at least for now. Let's see what the future brings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants