From 7fb29d002dbb8fa4b5945d1d1fe8dd164a9f7632 Mon Sep 17 00:00:00 2001 From: Ludy Date: Fri, 21 Aug 2026 11:32:16 +0000 Subject: [PATCH] deps(frontend): upgrade i18next ecosystem to v26 (#7356) # Description of Changes - Upgraded `i18next` to 26.3.6. - Upgraded `react-i18next` to 17.0.11. - Upgraded `i18next-browser-languagedetector` to 8.2.1. - Replaced the removed `initImmediate` option with `initAsync`. - Verified compatibility with the updated `` behavior and language detector APIs. - No translation changes were required because all `` usages use explicit `i18nKey` values. --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have run `task check` to verify linters, typechecks, and tests pass - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing) for more details. --- frontend/.storybook/preview.tsx | 8 +++--- frontend/editor/src/core/i18n.ts | 2 +- frontend/package-lock.json | 48 ++++++++++++-------------------- frontend/package.json | 6 ++-- 4 files changed, 26 insertions(+), 38 deletions(-) diff --git a/frontend/.storybook/preview.tsx b/frontend/.storybook/preview.tsx index f568b34347..5d36a0ca16 100644 --- a/frontend/.storybook/preview.tsx +++ b/frontend/.storybook/preview.tsx @@ -71,9 +71,9 @@ for (const [path, raw] of Object.entries(localeModules)) { } if (!i18next.isInitialized) { - // initImmediate: false → initialise synchronously from the inline resources - // (there's no async backend here), so i18next is ready before the first story - // renders. Without it the first render can beat init and stick on raw keys. + // initAsync: false → initialise synchronously from the inline resources. + // There is no asynchronous backend here, so i18next is ready before stories + // render. void i18next.use(initReactI18next).init({ lng: "en-US", fallbackLng: "en-US", @@ -81,7 +81,7 @@ if (!i18next.isInitialized) { resources, interpolation: { escapeValue: false }, react: { useSuspense: false }, - initImmediate: false, + initAsync: false, }); } else { // Something initialised i18next first (e.g. the app's async TOML backend): diff --git a/frontend/editor/src/core/i18n.ts b/frontend/editor/src/core/i18n.ts index 9663a1c2e2..839652658c 100644 --- a/frontend/editor/src/core/i18n.ts +++ b/frontend/editor/src/core/i18n.ts @@ -36,7 +36,7 @@ i18n debug: process.env.NODE_ENV === "development", // Ensure synchronous loading to prevent timing issues - initImmediate: false, + initAsync: false, interpolation: { escapeValue: false, // React already escapes values diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 00d8799e49..0d40c24959 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -62,8 +62,8 @@ "autoprefixer": "^10.4.21", "axios": "^1.15.0", "d3": "^7.9.0", - "i18next": "^25.10.10", - "i18next-browser-languagedetector": "^8.2.0", + "i18next": "^26.3.6", + "i18next-browser-languagedetector": "^8.2.1", "jszip": "^3.10.1", "license-report": "^6.8.0", "pdfjs-dist": "^5.4.149", @@ -74,7 +74,7 @@ "react": "^19.2.8", "react-dom": "^19.2.8", "react-easy-crop": "^5.5.6", - "react-i18next": "^16.6.6", + "react-i18next": "^17.0.11", "react-markdown": "^9.0.3", "react-rnd": "^10.5.2", "react-router-dom": "^7.9.1", @@ -10015,12 +10015,12 @@ "license": "MIT" }, "node_modules/html-parse-stringify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", - "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-4.0.1.tgz", + "integrity": "sha512-0zHsZJrK7S3K2aucXWL6ycoYJ/iNtIcFHC/nYQgFklPtrv5LpJctIiSCroWZWeuoXvuyFdzp6KzjJQ+OT5MfFw==", "license": "MIT", - "dependencies": { - "void-elements": "3.1.0" + "funding": { + "url": "https://locize.com" } }, "node_modules/html-tags": { @@ -10094,9 +10094,9 @@ } }, "node_modules/i18next": { - "version": "25.10.10", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.10.10.tgz", - "integrity": "sha512-cqUW2Z3EkRx7NqSyywjkgCLK7KLCL6IFVFcONG7nVYIJ3ekZ1/N5jUsihHV6Bq37NfhgtczxJcxduELtjTwkuQ==", + "version": "26.3.6", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-26.3.6.tgz", + "integrity": "sha512-Bu5Z2nAXgfVyM8xvW3jk9EKRIuX37PudsrBViThNFx7CR7aaYTpP01cxNB/E4c4UUzTDiAZRstEhsRfPOL/8xA==", "funding": [ { "type": "individual", @@ -10112,11 +10112,8 @@ } ], "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.29.2" - }, "peerDependencies": { - "typescript": "^5 || ^6" + "typescript": "^5 || ^6 || ^7" }, "peerDependenciesMeta": { "typescript": { @@ -13846,19 +13843,19 @@ } }, "node_modules/react-i18next": { - "version": "16.6.6", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-16.6.6.tgz", - "integrity": "sha512-ZgL2HUoW34UKUkOV7uSQFE1CDnRPD+tCR3ywSuWH7u2iapnz86U8Bi3Vrs620qNDzCf1F47NxglCEkchCTDOHw==", + "version": "17.0.11", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-17.0.11.tgz", + "integrity": "sha512-cDtkXgxjuFTWUH6V+aQn1Ve5vDiUztCNPWW5GtSHDccsgRXO1nE6QFWCEmc1KAutrb3OUv87wFShJL5RhUwPXg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.29.2", - "html-parse-stringify": "^3.0.1", + "html-parse-stringify": "^4.0.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { - "i18next": ">= 25.10.9", + "i18next": ">= 26.2.0", "react": ">= 16.8.0", - "typescript": "^5 || ^6" + "typescript": "^5 || ^6 || ^7" }, "peerDependenciesMeta": { "react-dom": { @@ -17462,15 +17459,6 @@ "dev": true, "license": "MIT" }, - "node_modules/void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/vue": { "version": "3.5.39", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.39.tgz", diff --git a/frontend/package.json b/frontend/package.json index 460f43f776..65ee25101c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -59,8 +59,8 @@ "autoprefixer": "^10.4.21", "axios": "^1.15.0", "d3": "^7.9.0", - "i18next": "^25.10.10", - "i18next-browser-languagedetector": "^8.2.0", + "i18next": "^26.3.6", + "i18next-browser-languagedetector": "^8.2.1", "jszip": "^3.10.1", "license-report": "^6.8.0", "pdfjs-dist": "^5.4.149", @@ -71,7 +71,7 @@ "react": "^19.2.8", "react-dom": "^19.2.8", "react-easy-crop": "^5.5.6", - "react-i18next": "^16.6.6", + "react-i18next": "^17.0.11", "react-markdown": "^9.0.3", "react-rnd": "^10.5.2", "react-router-dom": "^7.9.1",