From 09c645e6576fe30801ef180eaeba0ae51a00b476 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 19:25:59 +0200 Subject: [PATCH 01/14] Add dependency 'vue-i18n' --- THIRD_PARTY_LICENSES | 71 +++++++++++++++++++++++++++++++++++++ package-lock.json | 83 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 3 files changed, 155 insertions(+) diff --git a/THIRD_PARTY_LICENSES b/THIRD_PARTY_LICENSES index 5991212..b882793 100644 --- a/THIRD_PARTY_LICENSES +++ b/THIRD_PARTY_LICENSES @@ -364,6 +364,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ----------- +The following npm package may be included in this product: + + - @vue/devtools-api@6.6.4 + +This package contains the following license: + +MIT + +----------- + The following npm package may be included in this product: - json5@2.2.3 @@ -1371,6 +1381,67 @@ SOFTWARE. ----------- +The following npm packages may be included in this product: + + - @intlify/core-base@11.4.4 + - @intlify/message-compiler@11.4.4 + - @intlify/shared@11.4.4 + - vue-i18n@11.4.4 + +These packages each contain the following license: + +The MIT License (MIT) + +Copyright (c) 2020 kazuya kawaguchi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - @intlify/devtools-types@11.4.4 + +This package contains the following license: + +The MIT License (MIT) + +Copyright (c) 2024 kazuya kawaguchi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + The following npm package may be included in this product: - hookable@5.5.3 diff --git a/package-lock.json b/package-lock.json index b36f22c..4ca4615 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "terser": "^5.47.1", "vue": "^3.5.32", + "vue-i18n": "^11.4.4", "vue-router": "^5.0.6" }, "devDependencies": { @@ -106,6 +107,63 @@ "tslib": "^2.4.0" } }, + "node_modules/@intlify/core-base": { + "version": "11.4.4", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.4.4.tgz", + "integrity": "sha512-w/vItlylrAmhebkIbVl5YY8XMCtj8Mb2g70ttxktMYuf5AuRahgEHL2iLgLIsZBIbTSgs4hkUo7ucCL0uTJvOg==", + "dependencies": { + "@intlify/devtools-types": "11.4.4", + "@intlify/message-compiler": "11.4.4", + "@intlify/shared": "11.4.4" + }, + "engines": { + "node": ">= 22" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/devtools-types": { + "version": "11.4.4", + "resolved": "https://registry.npmjs.org/@intlify/devtools-types/-/devtools-types-11.4.4.tgz", + "integrity": "sha512-PcBLmGmDQsTSVV911P8upzpcLJO1CNVYi/IH6bGnLR2nA+0L963+kXN1ZrisTEnbtw2ewN6HMMSldqzjronA0Q==", + "dependencies": { + "@intlify/core-base": "11.4.4", + "@intlify/shared": "11.4.4" + }, + "engines": { + "node": ">= 22" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "11.4.4", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.4.4.tgz", + "integrity": "sha512-vn0OAV9pYkJlPPmgnsSm5eAG3mL0+9C/oaded2JY9jmxBbhmUXT3TcAUY8WRgLY9Hte7lkUJKpXrVlYjMXBD2w==", + "dependencies": { + "@intlify/shared": "11.4.4", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 22" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/shared": { + "version": "11.4.4", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.4.4.tgz", + "integrity": "sha512-QRUCHqda1U6aR14FR0vvXD4+4gj6+fm0AhAozvSuRCw0fCvrmCugWpgiR4xH2NI6s8am6N9p5OhirplsX8ZS3g==", + "engines": { + "node": ">= 22" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", @@ -2105,6 +2163,31 @@ } } }, + "node_modules/vue-i18n": { + "version": "11.4.4", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.4.4.tgz", + "integrity": "sha512-gIbXVSFQV4jcSJxfwdZ5zSZmZ+12CnX0K3vBkRSd6Zn+HSzCp+QwUgPwpD/uN0oKNKI9RzlUXPKVedEuMgNG0A==", + "dependencies": { + "@intlify/core-base": "11.4.4", + "@intlify/devtools-types": "11.4.4", + "@intlify/shared": "11.4.4", + "@vue/devtools-api": "^6.5.0" + }, + "engines": { + "node": ">= 22" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue-i18n/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + }, "node_modules/vue-router": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.6.tgz", diff --git a/package.json b/package.json index 644623f..7de1d0b 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "terser": "^5.47.1", "vue": "^3.5.32", + "vue-i18n": "^11.4.4", "vue-router": "^5.0.6" }, "devDependencies": { -- 2.39.5 From f37d4036368258647f93978baaa14e09beb98dae Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 19:39:56 +0200 Subject: [PATCH 02/14] Add base i18n --- src/i18n.js | 26 ++++++++++++++++++++++++++ src/main.js | 6 +++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/i18n.js diff --git a/src/i18n.js b/src/i18n.js new file mode 100644 index 0000000..b69ecb9 --- /dev/null +++ b/src/i18n.js @@ -0,0 +1,26 @@ +/* +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { createI18n } from 'vue-i18n'; + +export const fallbackLocale = 'en'; + +export const i18n = createI18n({ + legacy: false, + locale: 'en', + fallbackLocale: fallbackLocale, + messages: {} +}); \ No newline at end of file diff --git a/src/main.js b/src/main.js index 26903d1..6268da9 100644 --- a/src/main.js +++ b/src/main.js @@ -16,8 +16,12 @@ limitations under the License. import { createApp } from 'vue' import App from './App.vue' +import { i18n } from './i18n'; import router from './router' import './styles/common.css' import './styles/variables/colors.css' -createApp(App).use(router).mount('#app') +createApp(App) + .use(router) + .use(i18n) + .mount('#app') \ No newline at end of file -- 2.39.5 From 78cde4641c41b44d53336095c6a58baaba0fc5a8 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 19:43:14 +0200 Subject: [PATCH 03/14] Fix: Replace placeholer in the license header of 'src/i18n.js' with the actual values --- src/i18n.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n.js b/src/i18n.js index b69ecb9..5f20aaa 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -1,5 +1,5 @@ /* -Copyright [yyyy] [name of copyright owner] +Copyright 2026 Seekra Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. -- 2.39.5 From 2882f78990d572a6d4e8e13fca64a645b09517af Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 19:47:58 +0200 Subject: [PATCH 04/14] Adapt the language to the browser language --- src/i18n.js | 3 ++- src/utils/currentLanguage.js | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/utils/currentLanguage.js diff --git a/src/i18n.js b/src/i18n.js index 5f20aaa..ba02d36 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -15,12 +15,13 @@ limitations under the License. */ import { createI18n } from 'vue-i18n'; +import getCurrentLanguage from './utils/currentLanguage'; export const fallbackLocale = 'en'; export const i18n = createI18n({ legacy: false, - locale: 'en', + locale: getCurrentLanguage(), fallbackLocale: fallbackLocale, messages: {} }); \ No newline at end of file diff --git a/src/utils/currentLanguage.js b/src/utils/currentLanguage.js new file mode 100644 index 0000000..9aabb16 --- /dev/null +++ b/src/utils/currentLanguage.js @@ -0,0 +1,20 @@ +/* +Copyright 2026 Seekra + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +export default function getCurrentLanguage () { + const locale = new Intl.Locale(navigator.language); + return locale.language; +}; \ No newline at end of file -- 2.39.5 From 2eb187ec1a74b641320225216e88249a8981fcb1 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 21:05:09 +0200 Subject: [PATCH 05/14] Add function to load languages dynamically --- src/i18n.js | 18 +++++++++++++++++- src/main.js | 5 ++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/i18n.js b/src/i18n.js index ba02d36..bc11320 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -24,4 +24,20 @@ export const i18n = createI18n({ locale: getCurrentLanguage(), fallbackLocale: fallbackLocale, messages: {} -}); \ No newline at end of file +}); + +const loadedLanguages = new Set(); + +export async function loadLanguage (locale) { + if (loadedLanguages.has(locale)) { + i18n.global.locale.value = locale; + return; + }; + + const messages = (await import(`./locales/${locale}.json`)).default; + + i18n.global.setLocaleMessage(locale, messages); + i18n.global.locale.value = locale; + + loadedLanguages.add(locale); +}; \ No newline at end of file diff --git a/src/main.js b/src/main.js index 6268da9..e9ff0bc 100644 --- a/src/main.js +++ b/src/main.js @@ -16,11 +16,14 @@ limitations under the License. import { createApp } from 'vue' import App from './App.vue' -import { i18n } from './i18n'; +import { i18n, loadLanguage } from './i18n'; +import getCurrentLanguage from './utils/currentLanguage'; import router from './router' import './styles/common.css' import './styles/variables/colors.css' +await loadLanguage(getCurrentLanguage()); + createApp(App) .use(router) .use(i18n) -- 2.39.5 From 94fc328737cff4ceeafb5d5575e6a0ce71883e14 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 21:06:45 +0200 Subject: [PATCH 06/14] Add error handling if a locale to be loaded does not exist --- src/i18n.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/i18n.js b/src/i18n.js index bc11320..81765a0 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -19,6 +19,10 @@ import getCurrentLanguage from './utils/currentLanguage'; export const fallbackLocale = 'en'; +const SUPPORTED_LANGUAGES = [ + 'en' +]; + export const i18n = createI18n({ legacy: false, locale: getCurrentLanguage(), @@ -29,6 +33,10 @@ export const i18n = createI18n({ const loadedLanguages = new Set(); export async function loadLanguage (locale) { + if (!SUPPORTED_LANGUAGES.includes(locale)) { + locale = fallbackLocale; + } + if (loadedLanguages.has(locale)) { i18n.global.locale.value = locale; return; -- 2.39.5 From ced76720ccb1818ce792d709c3bbfb46bf86a946 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 21:07:44 +0200 Subject: [PATCH 07/14] Add English translations JSON file --- src/locales/en.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/locales/en.json diff --git a/src/locales/en.json b/src/locales/en.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/src/locales/en.json @@ -0,0 +1 @@ +{} \ No newline at end of file -- 2.39.5 From dd0f560bc86faf8d56bd32a7c6e23c52e5d435b4 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 21:14:07 +0200 Subject: [PATCH 08/14] Add translations for the search bar --- src/features/search/components/Searchbar.vue | 7 +++++-- src/locales/en.json | 9 ++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/features/search/components/Searchbar.vue b/src/features/search/components/Searchbar.vue index 8955b17..ac0f9df 100644 --- a/src/features/search/components/Searchbar.vue +++ b/src/features/search/components/Searchbar.vue @@ -18,6 +18,9 @@ limitations under the License. const searchQuery = defineModel(); import { useRouter } from 'vue-router'; +import { useI18n } from 'vue-i18n'; + +const { t } = useI18n(); const router = useRouter() const props = defineProps(['autoSubmit']) @@ -38,10 +41,10 @@ const submitSearch = function () { - + diff --git a/src/locales/en.json b/src/locales/en.json index 9e26dfe..57623cf 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1 +1,8 @@ -{} \ No newline at end of file +{ + "search": { + "searchBar": { + "submit": "Search", + "placeholder": "Search..." + } + } +} \ No newline at end of file -- 2.39.5 From 5d7181bea26d8df6b0def1a0eb865692a8b9f562 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 21:27:58 +0200 Subject: [PATCH 09/14] Add translations for error messages --- src/features/search/views/SearchResultsView.vue | 6 +++++- src/locales/en.json | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/features/search/views/SearchResultsView.vue b/src/features/search/views/SearchResultsView.vue index 40edb9d..fa565aa 100644 --- a/src/features/search/views/SearchResultsView.vue +++ b/src/features/search/views/SearchResultsView.vue @@ -17,6 +17,10 @@ limitations under the License. + -- 2.39.5 From 16e69ff072e6f7e63193a63ac83c404dd5498eae Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 19 May 2026 21:53:33 +0200 Subject: [PATCH 13/14] Add translations for the color scheme button --- .../components/ColorSchemeButton.vue | 19 ++++++++++--------- src/locales/en.json | 9 +++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/features/colorScheme/components/ColorSchemeButton.vue b/src/features/colorScheme/components/ColorSchemeButton.vue index ccda3c5..7a25065 100644 --- a/src/features/colorScheme/components/ColorSchemeButton.vue +++ b/src/features/colorScheme/components/ColorSchemeButton.vue @@ -16,6 +16,9 @@ limitations under the License.