Skip to content

Commit dbb20d1

Browse files
Add i18n-getAvailableLanguages() proposal
1 parent 4f1aed7 commit dbb20d1

1 file changed

Lines changed: 148 additions & 0 deletions

File tree

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# Proposal: `i18n.getAvailableLanguages()``
2+
3+
**Summary**
4+
5+
An API which allows extensions to get a list of BCP47 language tags containing
6+
the languages the browser can use and the extension provides resource files for.
7+
8+
**Document Metadata**
9+
10+
**Author:** carlosjeurissen
11+
12+
**Sponsoring Browser:** TBD
13+
14+
**Contributors:** hanguokai
15+
16+
**Created:** 2025-01-23
17+
18+
**Related Issues:** https://github.com/w3c/webextensions/issues/258 and https://github.com/w3c/webextensions/issues/274
19+
20+
## Motivation
21+
22+
### Objective
23+
24+
Currently extensions can not easily get a list of supported languages without
25+
hardcoding them first or need to rely on fetch try and error.
26+
27+
#### Use Cases
28+
29+
Allow to list the languages for extension settings language pickers.
30+
31+
Use the list of supported languages to match a specific website when applying
32+
a content script.
33+
34+
Have this list independent of distribution (As some extension stores disallow
35+
certain language tags).
36+
37+
Allow third parties to create polyfills for `i18n.withLanguage()` and
38+
`i18n.setLanguage()`.
39+
40+
### Known Consumers
41+
42+
Extensions who currently have to maintain a manually currated list of supported
43+
languages to offer content script language matching and/or allowing to change
44+
the extension language in the extension settings.
45+
46+
An example of content-script matching is "Category Tabs for Google Keep", which
47+
needs to match it's language with the page in question to properly integrate.
48+
49+
A simple naive implementation would be:
50+
```js
51+
const [pageLanguage, supportedLanguages] = await Promise.all([
52+
tabs.detectLanguage(),
53+
i18n.getAvailableLanguages(),
54+
]);
55+
const resourceLanguage = supportedLanguages.includes(pageLanguage);
56+
const resourceFile = chrome.runtime.getURL(`_locales/${resourceLanguage}/messages.json`);
57+
const messages = await fetch(resourceFile);
58+
```
59+
60+
Future consumers of future related APIs like the `i18n.withLanguage()` and
61+
`i18n.setLanguage()` APIs.
62+
63+
## Specification
64+
65+
### Schema
66+
67+
```typescript
68+
namespace i18n {
69+
function getAvailableLanguages(): Promise<string[]>;
70+
}
71+
```
72+
73+
This API should also be exposed in content scripts.
74+
75+
### Behavior
76+
77+
Given an extension with the following resource files:
78+
`_locales/en/messages.json`, `_locales/es/messages.json` and
79+
`_locales/es_419/messages.json`.
80+
81+
The `i18n.getAvailableLanguages()` method would return a promise which resolves
82+
with the following array: `['en', 'es', 'es-419']`.
83+
84+
If no resource files are specified, and/or `default_locale` in the manifest is
85+
missing, the promise will reject with an error stating extension localisation
86+
is required for this method to work properly.
87+
88+
If a browser is unable to offer a specific language tag in `i18n.withLanguage()`
89+
or `i18n.setLanguage()`, for example, because it does not understand the tag
90+
(think about `_locales/n/messages.json`), or if a directory has no messages.json
91+
file, it should not include said language tag. This does not mean a browser
92+
should only return languages the browser UI itself supports. An extension could
93+
offer additional languages outside the set of languages used for its own browser
94+
UI. In that case browsers can offer support for these languages and preferably
95+
should support and return them.
96+
97+
### New Permissions
98+
99+
No new permissions are needed.
100+
101+
### Manifest File Changes
102+
103+
No manifest file changes are required.
104+
105+
## Security and Privacy
106+
107+
### Exposed Sensitive Data
108+
109+
The returned information could in theory already be known to the extension. This
110+
information is not sensitive.
111+
112+
### Abuse Mitigations
113+
114+
As this does not expose sensitive data, there is no abuse potential.
115+
116+
### Additional Security Considerations
117+
118+
Exposing the list of locales an extension has resource files for is unlikely to
119+
introduce any new security risks.
120+
121+
## Alternatives
122+
123+
### Existing Workarounds
124+
125+
Extensions could hard-code the supported locale tags. This is however error
126+
prone as the list may be outdated. Some extensions may also reduce the list
127+
of included resource files for compatibility with specific extension stores. See
128+
https://forum.whale.naver.com/topic/39749/
129+
130+
### Open Web API
131+
132+
I18n resources are currently extension only. While there are talks about
133+
open web dom localization (See https://github.com/mozilla/explainers/blob/main/dom-localization.md)
134+
They are far from ready and their handling of resources will be different from
135+
current web extensions.
136+
137+
## Implementation Notes
138+
139+
Since this information will not change during the lifecycle of an extension. It
140+
can easily be cached on installation/update.
141+
142+
The locale tags need to be turned into a valid bcp47 tag. For example, for the
143+
resource `_locales/en_US`, the bcp47 tag `en-US` should be returned.
144+
145+
## Future Work
146+
147+
Allow to use `i18n.getMessage` with a different language. See https://github.com/w3c/webextensions/issues/274
148+
Allow to use change the language of extensions. See: https://github.com/w3c/webextensions/issues/258#issue-1344495962 and https://github.com/w3c/webextensions/pull/641

0 commit comments

Comments
 (0)