Skip to content

Commit

Permalink
🌍 fix: Enhance i18n Support & Optimize Category Handling (#5866)
Browse files Browse the repository at this point in the history
* fix: Missing Translations in Prompt Filters in Prompt Library

* fix: fixed issue with `zh`
feat: added `Estonian` language option

* fix: test for `i18n.ts`

* refactor: `pt` --> `pt-BR` and `pt-PT`

* feat: request access to another language. default is only one language during invite.
  • Loading branch information
rubentalstra authored Feb 14, 2025
1 parent 52a6de2 commit 04c2a5a
Show file tree
Hide file tree
Showing 33 changed files with 819 additions and 41 deletions.
42 changes: 42 additions & 0 deletions .github/ISSUE_TEMPLATE/LOCIZE_TRANSLATION_ACCESS_REQUEST.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Locize Translation Access Request
description: Request access to an additional language in Locize for LibreChat translations.
title: "Locize Access Request: "
labels: ["🌍 i18n", "🔑 access request"]
body:
- type: markdown
attributes:
value: |
Thank you for your interest in contributing to LibreChat translations!
Please fill out the form below to request access to an additional language in **Locize**.
**🔗 Available Languages:** [View the list here](https://www.librechat.ai/docs/translation)
**📌 Note:** Ensure that the requested language is supported before submitting your request.
- type: input
id: account_name
attributes:
label: Locize Account Name
description: Please provide your Locize account name (e.g., John Doe).
placeholder: e.g., John Doe
validations:
required: true
- type: input
id: language_requested
attributes:
label: Language Code (ISO 639-1)
description: |
Enter the **ISO 639-1** language code for the language you want to translate into.
Example: `es` for Spanish, `zh-Hant` for Traditional Chinese.
**🔗 Reference:** [Available Languages](https://www.librechat.ai/docs/translation)
placeholder: e.g., es
validations:
required: true
- type: checkboxes
id: agreement
attributes:
label: Agreement
description: By submitting this request, you confirm that you will contribute responsibly and adhere to the project guidelines.
options:
- label: I agree to use my access solely for contributing to LibreChat translations.
required: true
13 changes: 11 additions & 2 deletions .github/workflows/i18n-unused-keys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
pull_request:
paths:
- "client/src/**"
- "api/**"

jobs:
detect-unused-i18n-keys:
Expand All @@ -21,7 +22,7 @@ jobs:
# Define paths
I18N_FILE="client/src/locales/en/translation.json"
SOURCE_DIR="client/src"
SOURCE_DIRS=("client/src" "api")
# Check if translation file exists
if [[ ! -f "$I18N_FILE" ]]; then
Expand All @@ -37,7 +38,15 @@ jobs:
# Check if each key is used in the source code
for KEY in $KEYS; do
if ! grep -r --include=\*.{js,jsx,ts,tsx} -q "$KEY" "$SOURCE_DIR"; then
FOUND=false
for DIR in "${SOURCE_DIRS[@]}"; do
if grep -r --include=\*.{js,jsx,ts,tsx} -q "$KEY" "$DIR"; then
FOUND=true
break
fi
done
if [[ "$FOUND" == false ]]; then
UNUSED_KEYS+=("$KEY")
fi
done
Expand Down
19 changes: 10 additions & 9 deletions api/models/Categories.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
const { logger } = require('~/config');
// const { Categories } = require('./schema/categories');

const options = [
{
label: 'idea',
value: 'idea',
value: 'com_ui_idea',
},
{
label: 'travel',
value: 'travel',
value: 'com_ui_travel',
},
{
label: 'teach_or_explain',
value: 'teach_or_explain',
value: 'com_ui_teach_or_explain',
},
{
label: 'write',
value: 'write',
value: 'com_ui_write',
},
{
label: 'shop',
value: 'shop',
value: 'com_ui_shop',
},
{
label: 'code',
value: 'code',
value: 'com_ui_code',
},
{
label: 'misc',
value: 'misc',
value: 'com_ui_misc',
},
{
label: 'roleplay',
value: 'roleplay',
value: 'com_ui_roleplay',
},
{
label: 'finance',
value: 'finance',
value: 'com_ui_finance',
},
];

Expand Down
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"framer-motion": "^11.5.4",
"html-to-image": "^1.11.11",
"i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.3",
"js-cookie": "^3.0.5",
"librechat-data-provider": "*",
"lodash": "^4.17.21",
Expand Down
4 changes: 3 additions & 1 deletion client/src/components/Nav/SettingsTabs/General/General.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,17 @@ export const LangSelector = ({
const languageOptions = [
{ value: 'auto', label: localize('com_nav_lang_auto') },
{ value: 'en-US', label: localize('com_nav_lang_english') },
{ value: 'zh-CN', label: localize('com_nav_lang_chinese') },
{ value: 'zh-Hans', label: localize('com_nav_lang_chinese') },
{ value: 'zh-Hant', label: localize('com_nav_lang_traditional_chinese') },
{ value: 'ar-EG', label: localize('com_nav_lang_arabic') },
{ value: 'de-DE', label: localize('com_nav_lang_german') },
{ value: 'es-ES', label: localize('com_nav_lang_spanish') },
{ value: 'et-EE', label: localize('com_nav_lang_estonian') },
{ value: 'fr-FR', label: localize('com_nav_lang_french') },
{ value: 'it-IT', label: localize('com_nav_lang_italian') },
{ value: 'pl-PL', label: localize('com_nav_lang_polish') },
{ value: 'pt-BR', label: localize('com_nav_lang_brazilian_portuguese') },
{ value: 'pt-PT', label: localize('com_nav_lang_portuguese') },
{ value: 'ru-RU', label: localize('com_nav_lang_russian') },
{ value: 'ja-JP', label: localize('com_nav_lang_japanese') },
{ value: 'sv-SE', label: localize('com_nav_lang_swedish') },
Expand Down
14 changes: 7 additions & 7 deletions client/src/hooks/Prompts/useCategories.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { useGetCategories } from '~/data-provider';
import CategoryIcon from '~/components/Prompts/Groups/CategoryIcon';
import useLocalize from '~/hooks/useLocalize';
import useLocalize, { TranslationKeys } from '~/hooks/useLocalize';

const loadingCategories = [
const loadingCategories: { label: TranslationKeys; value: string }[] = [
{
label: 'Loading...',
label: 'com_ui_loading',
value: '',
},
] as undefined | { label: string; value: string }[];
];

const emptyCategory = {
label: '-',
const emptyCategory: { label: TranslationKeys; value: string } = {
label: 'com_ui_empty_category',
value: '',
};

Expand All @@ -19,7 +19,7 @@ const useCategories = (className = '') => {
const { data: categories = loadingCategories } = useGetCategories({
select: (data) =>
data.map((category) => ({
label: localize(`com_ui_${category.label}`) || category.label,
label: localize(category.label as TranslationKeys),
value: category.value,
icon: category.value ? (
<CategoryIcon category={category.value} className={className} />
Expand Down
15 changes: 5 additions & 10 deletions client/src/hooks/useLocalize.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useEffect, useCallback } from 'react';
import { useEffect } from 'react';
import { TOptions } from 'i18next';
import { useRecoilValue } from 'recoil';
import { useTranslation } from 'react-i18next';
import { TOptions } from 'i18next';
import store from '~/store';
import { resources } from '~/locales/i18n';
import store from '~/store';

export type TranslationKeys = keyof typeof resources.en.translation;

Expand All @@ -17,10 +17,5 @@ export default function useLocalize() {
}
}, [lang, i18n]);

const memoizedLocalize = useCallback(
(phraseKey: TranslationKeys, options?: TOptions) => t(phraseKey, options),
[t],
);

return memoizedLocalize;
}
return (phraseKey: TranslationKeys, options?: TOptions) => t(phraseKey, options);
}
5 changes: 2 additions & 3 deletions client/src/locales/Translation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ describe('i18next translation tests', () => {
expect(i18n.t('com_ui_examples')).toBe(English.com_ui_examples);
});

it('should return an empty string for an invalid key', () => {
it('should return the key itself for an invalid key', () => {
i18n.changeLanguage('en');
// @ts-ignore
expect(i18n.t('invalid-key')).toBe('');
expect(i18n.t('invalid-key')).toBe('invalid-key'); // Returns the key itself
});

it('should correctly format placeholders in the translation', () => {
Expand Down
3 changes: 3 additions & 0 deletions client/src/locales/ar/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@
"com_nav_lang_arabic": "العربية",
"com_nav_lang_auto": "اكتشاف تلقائي",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_chinese": "中文",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_finnish": "Suomi",
Expand All @@ -350,6 +352,7 @@
"com_nav_lang_swedish": "Svenska",
"com_nav_lang_turkish": "Türkçe",
"com_nav_lang_vietnamese": "Tiếng Việt",
"com_nav_lang_traditional_chinese": "繁體中文",
"com_nav_language": "اللغة",
"com_nav_latex_parsing": "تحليل LaTeX في الرسائل (قد يؤثر على الأداء)",
"com_nav_log_out": "تسجيل الخروج",
Expand Down
3 changes: 3 additions & 0 deletions client/src/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,9 @@
"com_nav_lang_arabic": "العربية",
"com_nav_lang_auto": "Automatisch erkennen",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_chinese": "中文",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_finnish": "Suomi",
Expand All @@ -357,6 +359,7 @@
"com_nav_lang_swedish": "Svenska",
"com_nav_lang_turkish": "Türkçe",
"com_nav_lang_vietnamese": "Tiếng Việt",
"com_nav_lang_traditional_chinese": "繁體中文",
"com_nav_language": "Sprache",
"com_nav_latex_parsing": "LaTeX in Nachrichten parsen (kann die Leistung beeinflussen)",
"com_nav_log_out": "Abmelden",
Expand Down
12 changes: 12 additions & 0 deletions client/src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,9 @@
"com_nav_lang_arabic": "العربية",
"com_nav_lang_auto": "Auto detect",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_chinese": "中文",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_finnish": "Suomi",
Expand Down Expand Up @@ -784,5 +786,15 @@
"com_ui_yes": "Yes",
"com_ui_zoom": "Zoom",
"com_user_message": "You",
"com_ui_loading": "Loading...",
"com_ui_finance": "Finance",
"com_ui_idea": "Ideas",
"com_ui_misc": "Misc.",
"com_ui_roleplay": "Roleplay",
"com_ui_shop": "Shopping",
"com_ui_teach_or_explain": "Learning",
"com_ui_travel": "Travel",
"com_ui_write": "Writing",
"com_ui_empty_category": "-",
"com_warning_resubmit_unsupported": "Resubmitting the AI message is not supported for this endpoint."
}
3 changes: 3 additions & 0 deletions client/src/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,9 @@
"com_nav_lang_arabic": "العربية",
"com_nav_lang_auto": "Detección automática",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_chinese": "中文",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_finnish": "Suomi",
Expand All @@ -350,6 +352,7 @@
"com_nav_lang_swedish": "Svenska",
"com_nav_lang_turkish": "Türkçe",
"com_nav_lang_vietnamese": "Tiếng Việt",
"com_nav_lang_traditional_chinese": "繁體中文",
"com_nav_language": "Idioma",
"com_nav_latex_parsing": "Analizar LaTeX en los mensajes (puede afectar el rendimiento)",
"com_nav_log_out": "Cerrar sesión",
Expand Down
3 changes: 3 additions & 0 deletions client/src/locales/et/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,9 @@
"com_nav_lang_arabic": "العربية",
"com_nav_lang_auto": "Tuvasta automaatselt",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_chinese": "中文",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_finnish": "Suomi",
Expand All @@ -362,6 +364,7 @@
"com_nav_lang_swedish": "Svenska",
"com_nav_lang_turkish": "Türkçe",
"com_nav_lang_vietnamese": "Tiếng Việt",
"com_nav_lang_traditional_chinese": "繁體中文",
"com_nav_language": "Keel",
"com_nav_latex_parsing": "LaTeXi parsimine sõnumites (võib mõjutada jõudlust)",
"com_nav_log_out": "Logi välja",
Expand Down
3 changes: 3 additions & 0 deletions client/src/locales/fi/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,9 @@
"com_nav_lang_arabic": "العربية",
"com_nav_lang_auto": "Tunnista automaattisesti",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_chinese": "中文",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_finnish": "Suomi",
Expand All @@ -287,6 +289,7 @@
"com_nav_lang_swedish": "Svenska",
"com_nav_lang_turkish": "Türkçe",
"com_nav_lang_vietnamese": "Tiếng Việt",
"com_nav_lang_traditional_chinese": "繁體中文",
"com_nav_language": "Kieli",
"com_nav_latex_parsing": "Tulkitse LaTeX:ia viesteissä (saattaa vaikuttaa suoritustehoon)",
"com_nav_log_out": "Kirjaudu ulos",
Expand Down
3 changes: 3 additions & 0 deletions client/src/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@
"com_nav_lang_arabic": "العربية",
"com_nav_lang_auto": "Détection automatique",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_chinese": "中文",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_finnish": "Suomi",
Expand All @@ -354,6 +356,7 @@
"com_nav_lang_swedish": "Svenska",
"com_nav_lang_turkish": "Türkçe",
"com_nav_lang_vietnamese": "Tiếng Việt",
"com_nav_lang_traditional_chinese": "繁體中文",
"com_nav_language": "Langue",
"com_nav_latex_parsing": "Analyse LaTeX dans les messages (peut affecter les performances)",
"com_nav_log_out": "Se déconnecter",
Expand Down
3 changes: 3 additions & 0 deletions client/src/locales/he/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@
"com_nav_hide_panel": "הסתר לוח הצד הימני ביותר",
"com_nav_lang_arabic": "العربية",
"com_nav_lang_brazilian_portuguese": "Português Brasileiro",
"com_nav_lang_portuguese": "Português",
"com_nav_lang_chinese": "中文",
"com_nav_lang_estonian": "Eesti keel",
"com_nav_lang_dutch": "Nederlands",
"com_nav_lang_english": "English",
"com_nav_lang_finnish": "Suomi",
Expand All @@ -208,6 +210,7 @@
"com_nav_lang_swedish": "Svenska",
"com_nav_lang_turkish": "Türkçe",
"com_nav_lang_vietnamese": "Tiếng Việt",
"com_nav_lang_traditional_chinese": "繁體中文",
"com_nav_latex_parsing": "ניתוח LaTeX בהודעות (עשוי להשפיע על הביצועים)",
"com_nav_log_out": "צא",
"com_nav_modular_chat": "אפשר החלפת נקודות קצה באמצע שיחה",
Expand Down
Loading

0 comments on commit 04c2a5a

Please sign in to comment.