diff --git a/README.md b/README.md index 120431f8..49646a5c 100644 --- a/README.md +++ b/README.md @@ -101,29 +101,55 @@ Preferences -> Tools -> Actions on Save ## Translations -We use (Locize)[https://locize.com] together with (i18next)[https://www.i18next.com/] +We use (Locize)[https://locize.com] (see 1Password for credentials) +together with (i18next)[https://www.i18next.com/] for translations on the Frontend. -The master for translated files is on Locize. Missing keys get automatically added to -Locize, no manual step is needed. -The translations are done on Locize. - Please make sure that the required environment variables are set (see ./env_secrets/local_daniel.env for the values): * LOCIZE_PROJECT_ID * LOCIZE_API_KEY +The master for translated files is on Locize! +That means, that the app will take the translations/texts from Locize +to show in the app. The files in ./client/locales are only used as reference and are not the master! -But you can still sync the local locale files with Locize with the following command. -Please be careful and do not lose translations. The savest way is to only add the -keys to the German file and let Locize translate them. +There are multiple ways on how to add new translations to Locize: + +### Process one: Let Locize add missing keys automatically + +When running the app, it will automatically add the missing translation +keys to Locize. +There you can translate them, and also add the German translation. + +### Process two: Add keys manually + +You can add the new keys manually to the German locale file in +./client/locales/de/translation.json + +Then you can run the following command to add the keys to Locize: + +### Helpers + +The following command could help find missing and/or unused keys. +But manual review is still needed. + +```bash +npx vue-i18n-extract report --vueFiles './src/**/*.?(ts|vue)' --languageFiles './src/locales/**/*.?(json|yml|yaml)' +``` ```bash npm run locize:sync ``` +The command will add the keys and the German translation to Locize. + +Bonus: Use the "i18n ally" plugin in VSCode or IntelliJ to get extract untranslated +texts directly from the code to the translation.json file. + + ### "_many" plural form in French and Italian See https://github.com/i18next/i18next/issues/1691#issuecomment-968063348 diff --git a/client/package.json b/client/package.json index 86edfa69..b7857295 100644 --- a/client/package.json +++ b/client/package.json @@ -17,7 +17,7 @@ "tailwind": "tailwindcss -i tailwind.css -o ../server/vbv_lernwelt/static/css/tailwind.css --watch", "test": "vitest run", "typecheck": "npm run codegen && vue-tsc --noEmit -p tsconfig.app.json --composite false", - "locize:sync": "locize sync --path ./src/locales" + "locize:sync": "locize sync --path ./src/locales --compare-modification-time=true" }, "dependencies": { "@headlessui/tailwindcss": "^0.1.3", diff --git a/client/src/i18nextWrapper.ts b/client/src/i18nextWrapper.ts index 0ede6b5d..4d3d0d3b 100644 --- a/client/src/i18nextWrapper.ts +++ b/client/src/i18nextWrapper.ts @@ -1,8 +1,7 @@ import type { AvailableLanguages } from "@/stores/user"; import i18next from "i18next"; -import { locizePlugin } from "locize"; - import Backend from "i18next-locize-backend"; +import { locizePlugin } from "locize"; import { nextTick } from "vue"; @@ -26,13 +25,18 @@ export function i18nextInit() { .use(locizePlugin) .init({ debug: true, + supportedLngs: SUPPORT_LOCALES, fallbackLng: "de", defaultNS: "translation", returnNull: false, - saveMissing: true, + saveMissing: import.meta.env.DEV, backend: { - projectId: import.meta.env.VITE_LOCIZE_PROJECTID, - apiKey: import.meta.env.VITE_LOCIZE_API_KEY, + projectId: + import.meta.env.VITE_LOCIZE_PROJECTID || + "7518c269-cbf7-4d25-bc5c-6ceba2a8b74b", + apiKey: import.meta.env.DEV ? import.meta.env.VITE_LOCIZE_API_KEY : undefined, + fallbackLng: "de", + allowedAddOrUpdateHosts: ["localhost"], }, }) ); @@ -52,6 +56,7 @@ export function setI18nLanguage(locale: string) { export async function loadI18nextLocaleMessages(locale: any) { // load locale messages with dynamic import + // unused with locize const messages = await import(`./locales/${locale}.json`); i18next.addResourceBundle(locale, "messages", messages, true, true); diff --git a/client/src/locales/de/translation.json b/client/src/locales/de/translation.json index 2324d56a..8b7fe597 100644 --- a/client/src/locales/de/translation.json +++ b/client/src/locales/de/translation.json @@ -123,6 +123,9 @@ "veryHappy": "Sehr zufrieden", "veryUnhappy": "Sehr unzufrieden" }, + "foobar": { + "hello": "Hallo von der Innoweek" + }, "footer": { "contact": "Kontakt", "contactLink": "https://www.vbv.ch/de/der-vbv/organisation/kontakt", @@ -236,6 +239,5 @@ }, "settings": { "emailNotifications": "Email Benachrichtigungen" - }, - "welcome": "Hallo Welt" -} + } +} \ No newline at end of file diff --git a/client/src/locales/fr/translation.json b/client/src/locales/fr/translation.json index c1878e1c..fa1ff6fb 100644 --- a/client/src/locales/fr/translation.json +++ b/client/src/locales/fr/translation.json @@ -123,6 +123,9 @@ "veryHappy": "Très satisfait(e)", "veryUnhappy": "Très insatisfait(e)" }, + "foobar": { + "hello": "Salut Innoweek" + }, "footer": { "contact": "Contact", "contactLink": "https://www.vbv.ch/fr/lafa/organisation/contact", @@ -244,4 +247,4 @@ "settings": { "emailNotifications": "Notifications par e-mail" } -} +} \ No newline at end of file diff --git a/client/src/locales/it/translation.json b/client/src/locales/it/translation.json index c8be8b01..64d5ec68 100644 --- a/client/src/locales/it/translation.json +++ b/client/src/locales/it/translation.json @@ -123,6 +123,9 @@ "veryHappy": "Molto soddisfatto/a", "veryUnhappy": "Molto insoddisfatto/a" }, + "foobar": { + "hello": "Ciao Innoweek" + }, "footer": { "contact": "Contatti", "contactLink": "https://www.vbv.ch/it/afa/organizzazione/contatto", @@ -244,4 +247,4 @@ "settings": { "emailNotifications": "Notifiche e-mail" } -} +} \ No newline at end of file