Not clear that there are three(?) locales

I’ve read all that documentation here:

But it’s still not clear whether i18n.getMessage() uses the locale i18n.getUILanguage() or i18n.getAcceptLanguages() returns.

So one the one hand, I’d think this:

  • accept-language is basically what’s used in the HTTP header, so actually would have nothing to do with a browser/browser extension.
  • UI language is what is part of the browser. And the extension is likely considered a part of the browser.

So the docs states me to change two simple prefs (both set to “de”) and. To be extra sure, I also just modified the usual visible options:
grafik

So, afterwards, as the doc correctly says: My manifest is being translated and correctly displayed in about:addons.

However, getMessage still returns the English strings.
BTW, in my case it’s a popup, not a notification being translated, but I thought JS is the same. I only now notice it talks about the CSS/manifest.json translation there.

Maybe the behaviour can be explained, because, the doc then states:

To change the result of getUILanguage the language pack is required, since it reflects the browser UI language and not the language used for extension messages.

That comes a bit late… So as far as I understand it, it uses intl.locale.requested for about:addons and CSS; the browser’s UI locale for JS requests and the whole “user request” locale is still unrelated to this(?). How many locales do we even have here?? :open_mouth:
I finally tested it in stable with a German language pack installed, and voila: There it works.

I’d like these changes:

  • There should be a clear statement: If you want to get the language getMessage uses when it localizes text, you should use XY. Or maybe one can (or should?) even use @@ui_locale here? I.e. i18n.getMessage("@@ui_locale")?
  • The testing part is confusing.
    I think the fact that it seems to use the 2 (or 3) different locales is a big point of confusion. Maybe you can avoid it by clearly separating between these, as users not knowing this might think:

    “Okay, we have one locale for the browser UI/extensions, and that’s how they tell me to test it. Sure, website locale may be different, I don’t care.
    Okay, my test does not work. Oh at the bottom it tells me the browser locale is not the one of the extension…?!”

1 Like

tagging @zbraniecki to find out if there’s more docs we need to update.

  • getMessage tries to use the best fitting language the extension provides, since extensions rarely have exactly the same locales as Firefox.
  • getUILanguage returns the best-fitting Firefox UI language that was found (i.e. the one used for the general Firefox UI).
  • getAcceptLanguages is what is sent in the HTTP header, correct.
  • The text in about:addons is translated with getMessage OR by the description provided on AMO.

I don’t think you can get the language that getMessage is using without adding a custom message to your messages.json that returns the language of the currently used messages.json.

1 Like

Oh, that’s bad, but would not that be useful? Actually all the other methods are kinda useless for localization, because in an extreme case it may happen that I have a Turkish Firefox UI, a HTTP header/accept language with German and as the add-on does not provide translations, getMessage falls back to English.
Now when the add-on tries to get it’s own language it is translated all these calls return the wrong language.
And yet the tutorial tells me I can use them “to customize the UI depending on the locale”, which might really be an edge-case. (only usable when the add-on itself has something to do with translations/locales).

So if I want to do such a simple thing as getting “my own language”, I really have to resort to workarounds?

  • As you say: Oh, yeah
  • or, even “funnier”, use i18n.detectLanguage() on a string I get with getMessage :laughing:

I wonder whether we could not use @@ui_locale" somehow, as this seems to be what is wanted… But (not tested) i18n.getMessage("@@ui_locale") would not work, does not? (That would be exactly what I want.) These are yet again only available for CSS and manifests, are not they?

So okay, kinda strange situation. You can get two language(s/ values), which are only slightly related to i18n, but not the your add-on is actually displayed in.

getMessage should use getUILanguage. The question is what should happen if Firefox uses a different language than the extension. What should getUILanguage return?

Wrt. docs - the docs are written and just need to get reviewed and landed in https://bugzilla.mozilla.org/show_bug.cgi?id=1438687 .

The discussion about ability to decouple extensions locale selection from Firefox is here: https://bugzilla.mozilla.org/show_bug.cgi?id=1440969

Tagging @wbamberg just in case there is anything he needs to be aware of here (that he isn’t already), WRT WebExt docs.

It does not prefer the current browser UI language over any other available language, instead it uses the same negotiation as used for the browser UI language. Meaning that if you have a Firefox that for example only has the en-US langpack but the OS is in a different language and the extension has translations for that language, the extension will not be en-US, even if it had en-US strings.

Yep, that’s on purpose. Extensions are considered part of Fx UI so we tailor them down to match Fx UI locale selection as much as possible.

As I listed above there’s a bug to add an option to relax that and allow extensions to have their own independent negotiation (for example for testing purposes).

My point is that they are not tailored down to match the Firefox UI locale as close as possible, they are tailored to match the requested locale as close as possible. And the requested locale is not the UI locale of Firefox.

What do you base this claim on?

Here’s the code:

If I’m not mistaken those are the two places where locales for extensions are negotiated. In both cases the requested list is the list of locales resolved for Firefox UI which means that we do tailor it down to match the Firefox UI locale selection as close as possible.

Am I missing something?

Yes, this negotiation strategy doesn’t try to match the UI language, it tries to match the requested UI language. Trying to match the UI language would mean putting it first and only falling back to other languages if that language is not available in the extension.

I’ve recently seen another extension developer confused by the potential dissonance between the Firefox UI language (getUILanguage()) and the language used with getMessage, since you need a language pack to influence the actual UI language, but you don’t need one to change the language used by getMessage, as it doesn’t try to use the current Firefox UI language first, but tries to match the requested UI language.

I’m not sure if actually matching the UI language is desired behavior to start with, but saying that getMessage tries to match the UI language is not correct. It tries to match the requested language.

1 Like

I really struggle to understand what you claim here, and I’m the author of the referenced code, so that’s confusing.

The negotiation strategy does try to match the negotiated Firefox UI locale set against the list of locales available in the addon.

That’s what the code I referenced does.

Can you please reference the code you claim to do something different?

https://searchfox.org/mozilla-central/source/toolkit/mozapps/extensions/internal/XPIProvider.jsm#4382 - this gets the same list as is used to negotiate the UI language.

Which means the description to an extension is not necessarily matching the browser UI language. In fact, if I set intl.locale.requested to something that I don’t have installed but the extension provides I see that description and the add-on name in the requested language and not the UI language,

Sorry about my confusion, getMessage is negotiated as expected and the documentation is wrong (that you don’t need a langpack to test getMessage results).

1 Like

Ah, now I see it! Yes, that’s inconsistent and IIRC Kris was planning to change that. I’ll sync with him. Thanks for being patient and explaining your understanding!

1 Like

So when this is fixed, the following statement should be correct:

(Basically that’s all I’ve asked.)
Then this should be documented in MDN.

1 Like

Note the doc for i18n.getUILanguage() still does not mention, it is not (only) the browser’s language (as the function name implies), but also the language of the add-on. Should not this also be chnaged?