Skip to content

Commit 6d48167

Browse files
loiswells97Copilot
andauthored
Add locale attribute instead of detecting language (#1244)
Switches to determining the language from an attribute rather than detecting through `i81n`. This maintains independence from the setup of the host page whilst allowing the web component to be consistent with the host in its choice of language. closes RaspberryPiFoundation/digital-editor-issues#883 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 729e5a1 commit 6d48167

File tree

8 files changed

+31
-19
lines changed

8 files changed

+31
-19
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1616
- Improved status bar styling (#1221)
1717
- Added method to translate last saved time (#1223)
1818
- Deleting unused strings and components (#1225)
19+
- Determine locale from web component attribute instead of browser path (#1244)
1920

2021
### Fixed
2122

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ The `editor-wc` tag accepts the following attributes, which must be provided as
6666
- `instructions`: Stringified JSON containing steps to be displayed in the instructions panel in the sidebar
6767
- `load_cache`: Load latest version of project code from local storage (defaults to `true`)
6868
- `load_remix_disabled`: Do not load a logged-in user's remixed version of the project specified by `identifier` even if one exists (defaults to `false`)
69+
- `locale`: Locale for UI elements and to determine the language of projects loaded from the API (defaults to `en`)
6970
- `output_only`: Only display the output panel (defaults to `false`)
7071
- `output_panels`: Array of output panel names to display (defaults to `["text", "visual"]`)
7172
- `output_split_view`: Start with split view in output panel (defaults to `false`, i.e. tabbed view)

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
"highcharts": "^9.3.1",
3939
"highcharts-react-official": "^3.1.0",
4040
"i18next": "^22.0.3",
41-
"i18next-browser-languagedetector": "^7.0.0",
4241
"i18next-http-backend": "^3.0.2",
4342
"identity-obj-proxy": "3.0.0",
4443
"jest-axe": "^7.0.0",

src/containers/WebComponentLoader.jsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const WebComponentLoader = (props) => {
4343
instructions,
4444
theme,
4545
loadRemixDisabled = false,
46+
locale = "en",
4647
outputOnly = false,
4748
outputPanels = ["text", "visual"],
4849
outputSplitView = false,
@@ -87,6 +88,8 @@ const WebComponentLoader = (props) => {
8788
(state) => state.editor.renameFileModalShowing,
8889
);
8990

91+
const { i18n } = useTranslation();
92+
9093
const [cookies, setCookie] = useCookies(["theme", "fontSize"]);
9194
const themeDefault = window.matchMedia("(prefers-color-scheme:dark)").matches
9295
? "dark"
@@ -127,6 +130,12 @@ const WebComponentLoader = (props) => {
127130
}
128131
}, [projectOwner, justLoaded]);
129132

133+
useEffect(() => {
134+
if (locale) {
135+
i18n.changeLanguage(locale);
136+
}
137+
}, [locale, i18n]);
138+
130139
useProject({
131140
reactAppApiEndpoint,
132141
projectIdentifier: projectIdentifier,

src/containers/WebComponentLoader.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ jest.mock("../hooks/useProjectPersistence", () => ({
2424
useProjectPersistence: jest.fn(),
2525
}));
2626

27+
const mockedChangeLanguage = jest.fn(() => new Promise(() => {}));
28+
29+
jest.mock("react-i18next", () => ({
30+
useTranslation: () => {
31+
return {
32+
i18n: {
33+
changeLanguage: mockedChangeLanguage,
34+
},
35+
t: (str) => str,
36+
};
37+
},
38+
}));
39+
2740
let store;
2841
let cookies;
2942
const code = "print('This project is amazing')";
@@ -69,6 +82,7 @@ describe("When initially rendered", () => {
6982
instructions={instructions}
7083
authKey={authKey}
7184
theme="light"
85+
locale="es-LA"
7286
/>
7387
</CookiesProvider>
7488
</Provider>,
@@ -90,6 +104,10 @@ describe("When initially rendered", () => {
90104
expect(window.syntaxHighlight).toEqual(window.Prism);
91105
});
92106

107+
test("it sets the language in i18n", () => {
108+
expect(mockedChangeLanguage).toHaveBeenCalledWith("es-LA");
109+
});
110+
93111
describe("react app API endpoint", () => {
94112
describe("when react app API endpoint isn't set", () => {
95113
beforeEach(() => {

src/utils/i18n.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import i18n from "i18next";
22
import { initReactI18next } from "react-i18next";
3-
import LanguageDetector from "i18next-browser-languagedetector";
43
import HttpBackend from "i18next-http-backend";
54

65
i18n
7-
// detect user language
8-
// learn more: https://github.com/i18next/i18next-browser-languageDetector
9-
.use(LanguageDetector)
106
// pass the i18n instance to react-i18next.
117
.use(initReactI18next)
128
// init i18next
@@ -104,9 +100,6 @@ i18n
104100
load: "currentOnly", // otherwise for fr-FR it's load ['fr-FR', 'fr']
105101

106102
// nonExplicitSupportedLngs: true, // allows locale variants on supportedLngs
107-
detection: {
108-
order: ["path"], // only use path to detect local for now
109-
},
110103

111104
interpolation: {
112105
escapeValue: false, // not needed for react!!

src/web-component.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class WebComponent extends HTMLElement {
5757
"identifier",
5858
"instructions",
5959
"load_remix_disabled",
60+
"locale",
6061
"output_only",
6162
"output_panels",
6263
"output_split_view",

yarn.lock

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,7 +1611,7 @@ __metadata:
16111611
languageName: node
16121612
linkType: hard
16131613

1614-
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.24.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2":
1614+
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.24.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2":
16151615
version: 7.25.7
16161616
resolution: "@babel/runtime@npm:7.25.7"
16171617
dependencies:
@@ -2816,7 +2816,6 @@ __metadata:
28162816
highcharts-react-official: ^3.1.0
28172817
html-webpack-plugin: 5.6.0
28182818
i18next: ^22.0.3
2819-
i18next-browser-languagedetector: ^7.0.0
28202819
i18next-http-backend: ^3.0.2
28212820
identity-obj-proxy: 3.0.0
28222821
jest: ^29.1.2
@@ -10131,15 +10130,6 @@ __metadata:
1013110130
languageName: node
1013210131
linkType: hard
1013310132

10134-
"i18next-browser-languagedetector@npm:^7.0.0":
10135-
version: 7.2.1
10136-
resolution: "i18next-browser-languagedetector@npm:7.2.1"
10137-
dependencies:
10138-
"@babel/runtime": ^7.23.2
10139-
checksum: 159958be2d8f19444e9378512c36c2bf13a8ab85eddac2fc0000198a03dbc28c73a6f44594ab040b242bdc82dfeabb7c1ab805884b5438ee0a48a8e2b52ca062
10140-
languageName: node
10141-
linkType: hard
10142-
1014310133
"i18next-http-backend@npm:^3.0.2":
1014410134
version: 3.0.2
1014510135
resolution: "i18next-http-backend@npm:3.0.2"

0 commit comments

Comments
 (0)