Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌍 fix: Enhance i18n Support & Optimize Category Handling #5866

Merged
merged 5 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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