From b964bca877c5c2084df362bac4ffb9f64c1522f5 Mon Sep 17 00:00:00 2001 From: "D. Ror." Date: Wed, 28 Aug 2024 10:37:54 -0400 Subject: [PATCH] Update and consolidate i18n (#3313) --- package-lock.json | 32 ++++++++++++------------ package.json | 6 ++--- src/{i18n.ts => i18n/index.ts} | 10 ++++---- src/{ => i18n}/tests/i18nMock.ts | 4 +-- src/{ => i18n}/tests/reactI18nextMock.ts | 4 +-- src/setupTests.js | 2 +- 6 files changed, 29 insertions(+), 29 deletions(-) rename src/{i18n.ts => i18n/index.ts} (84%) rename src/{ => i18n}/tests/i18nMock.ts (84%) rename src/{ => i18n}/tests/reactI18nextMock.ts (75%) diff --git a/package-lock.json b/package-lock.json index e12e7e32be..189e5e3706 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,9 +27,9 @@ "distinct-colors": "^3.0.0", "history": "^5.3.0", "http-status-codes": "^2.3.0", - "i18next": "^23.4.6", + "i18next": "^23.14.0", "i18next-browser-languagedetector": "^8.0.0", - "i18next-http-backend": "^2.2.2", + "i18next-http-backend": "^2.6.0", "js-base64": "^3.7.7", "make-dir": "^4.0.0", "material-react-table": "^2.9.2", @@ -42,7 +42,7 @@ "react-beautiful-dnd": "^13.1.1", "react-chartjs-2": "^5.2.0", "react-dom": "^18.2.0", - "react-i18next": "^14.1.2", + "react-i18next": "^15.0.1", "react-modal": "^3.16.1", "react-redux": "^8.1.3", "react-router-dom": "^6.16.0", @@ -2130,9 +2130,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -14391,9 +14391,9 @@ } }, "node_modules/i18next": { - "version": "23.11.5", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.5.tgz", - "integrity": "sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==", + "version": "23.14.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.14.0.tgz", + "integrity": "sha512-Y5GL4OdA8IU2geRrt2+Uc1iIhsjICdHZzT9tNwQ3TVqdNzgxHToGCKf/TPRP80vTCAP6svg2WbbJL+Gx5MFQVA==", "funding": [ { "type": "individual", @@ -14421,9 +14421,9 @@ } }, "node_modules/i18next-http-backend": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.5.2.tgz", - "integrity": "sha512-+K8HbDfrvc1/2X8jpb7RLhI9ZxBDpx3xogYkQwGKlWAUXLSEGXzgdt3EcUjLlBCdMwdQY+K+EUF6oh8oB6rwHw==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.6.0.tgz", + "integrity": "sha512-WX5pXYNrAz2fj8ajsAuCIsogOEvJL+aHw4RTQAD/uqPoLV1FHqa6IsUULTfa3GtREVQbApp0U3woLhz9EuR2pQ==", "dependencies": { "cross-fetch": "4.0.0" } @@ -20714,11 +20714,11 @@ "dev": true }, "node_modules/react-i18next": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz", - "integrity": "sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.1.tgz", + "integrity": "sha512-NwxLqNM6CLbeGA9xPsjits0EnXdKgCRSS6cgkgOdNcPXqL+1fYNl8fBg1wmnnHvFy812Bt4IWTPE9zjoPmFj3w==", "dependencies": { - "@babel/runtime": "^7.23.9", + "@babel/runtime": "^7.24.8", "html-parse-stringify": "^3.0.1" }, "peerDependencies": { diff --git a/package.json b/package.json index 9f9117af55..9490b13e1f 100644 --- a/package.json +++ b/package.json @@ -55,9 +55,9 @@ "distinct-colors": "^3.0.0", "history": "^5.3.0", "http-status-codes": "^2.3.0", - "i18next": "^23.4.6", + "i18next": "^23.14.0", "i18next-browser-languagedetector": "^8.0.0", - "i18next-http-backend": "^2.2.2", + "i18next-http-backend": "^2.6.0", "js-base64": "^3.7.7", "make-dir": "^4.0.0", "material-react-table": "^2.9.2", @@ -70,7 +70,7 @@ "react-beautiful-dnd": "^13.1.1", "react-chartjs-2": "^5.2.0", "react-dom": "^18.2.0", - "react-i18next": "^14.1.2", + "react-i18next": "^15.0.1", "react-modal": "^3.16.1", "react-redux": "^8.1.3", "react-router-dom": "^6.16.0", diff --git a/src/i18n.ts b/src/i18n/index.ts similarity index 84% rename from src/i18n.ts rename to src/i18n/index.ts index 98f531cc23..e68d4a3222 100644 --- a/src/i18n.ts +++ b/src/i18n/index.ts @@ -1,7 +1,7 @@ // https://dev.to/adrai/how-to-properly-internationalize-a-react-application-using-i18next-3hdb#getting-started import i18n from "i18next"; import LanguageDetector from "i18next-browser-languagedetector"; -import Backend from "i18next-http-backend"; +import Backend, { type HttpBackendOptions } from "i18next-http-backend"; import { initReactI18next } from "react-i18next"; import { getCurrentUser } from "backend/localStorage"; @@ -18,17 +18,17 @@ i18n .use(Backend) .use(LanguageDetector) .use(initReactI18next) - .init( + .init( { //debug: true, // Uncomment to troubleshoot returnNull: false, - // detection: options, // ignoring localStorage and cookies for the detection order lets the user change languages // more easily (just switch in the browser and reload, instead of clearing all site data) detection: { order: ["queryString", "path", "navigator"] }, supportedLngs: i18nLangs, - // nonExplicitSupportedLngs will (e.g.) use 'es' if the browser is 'es-MX' - nonExplicitSupportedLngs: true, + // "languageOnly" means use only the language part (first subtag) of the full language tag; + // e.g., if the user's browser is set to 'es-MX', we just use 'es' + load: "languageOnly", fallbackLng: i18nFallbacks, interpolation: { escapeValue: false }, }, diff --git a/src/tests/i18nMock.ts b/src/i18n/tests/i18nMock.ts similarity index 84% rename from src/tests/i18nMock.ts rename to src/i18n/tests/i18nMock.ts index f108ddcd06..0a67071037 100644 --- a/src/tests/i18nMock.ts +++ b/src/i18n/tests/i18nMock.ts @@ -1,9 +1,9 @@ /* Adapted from https://react.i18next.com/misc/testing * (In most cases, this isn't needed. - * Instead you can use tests/reactI18nextMock.ts to mock out i18n completely.) + * Instead you can use i18n/tests/reactI18nextMock.ts to mock out i18n completely.) * For a simple i18next wrapper, add the following to a test file: * * import { I18nextProvider } from "react-i18next"; - * * import i18n from "tests/i18nMock"; + * * import i18n from "i18n/tests/i18nMock"; * Then wrap the component being rendered with */ import i18n from "i18next"; diff --git a/src/tests/reactI18nextMock.ts b/src/i18n/tests/reactI18nextMock.ts similarity index 75% rename from src/tests/reactI18nextMock.ts rename to src/i18n/tests/reactI18nextMock.ts index fbb2f61084..46ff6ec245 100644 --- a/src/tests/reactI18nextMock.ts +++ b/src/i18n/tests/reactI18nextMock.ts @@ -1,5 +1,5 @@ -/* Use `import "tests/reactI18nextMock.ts";` in `setupTests.js` to mock i18next globally. - * (For testing components with `Trans`, see tests/i18nMock.ts instead.) +/* Use `import "i18n/tests/reactI18nextMock.ts";` in `setupTests.js` to mock i18next globally. + * (For testing components with `Trans`, see i18n/tests/i18nMock.ts instead.) * This import should occur before other internal imports that use `react-i18next`. */ jest.mock("react-i18next", () => ({ diff --git a/src/setupTests.js b/src/setupTests.js index 3cda883c66..6f054fd527 100644 --- a/src/setupTests.js +++ b/src/setupTests.js @@ -1,4 +1,4 @@ -import "tests/reactI18nextMock"; +import "i18n/tests/reactI18nextMock"; // Force tests to fail on console.error and console.warn global.console.error = (message) => {