Multi-Language Platform — 5 Languages
Trade in Your
Own Language.
Guro Markets supports 5 languages with full RTL support for Arabic. Every page, every button, every AI response — fully translated and culturally adapted.
English
English
LTR"Trade Like a Master"
Arabic
العربية
RTL ←"تداول كالمحترف"
French
Français
LTR"Tradez comme un maître"
Spanish
Español
LTR"Opera como un maestro"
Swahili
Kiswahili
LTR"Fanya biashara kama bingwa"
Click any language card to see the platform in that language. Arabic includes full RTL layout mirroring.
Translation System
Full Platform Translation Keys
All UI strings are externalised into translation files. APEX AI responses are also dynamically translated per user's language preference.
| Key | English | Arabic عربي | Français | Español | Kiswahili |
|---|---|---|---|---|---|
| nav.dashboard | Dashboard | لوحة التحكم | Tableau de bord | Panel de control | Dashibodi |
| nav.trade | Trade Markets | تداول الأسواق | Marchés de trading | Mercados de trading | Biashara ya Masoko |
| nav.wallet | My Wallet | محفظتي | Mon portefeuille | Mi cartera | Mkoba wangu |
| dashboard.deposit | Deposit | إيداع | Dépôt | Depositar | Weka pesa |
| trade.buy | Buy | شراء | Acheter | Comprar | Nunua |
| trade.sell | Sell | بيع | Vendre | Vender | Uza |
| trade.stop_loss | Stop Loss | وقف الخسارة | Stop loss | Stop loss | Simamisha hasara |
| trade.take_profit | Take Profit | جني الأرباح | Prendre profit | Tomar ganancias | Chukua faida |
| prop.profit_target | Profit Target | هدف الربح | Objectif de profit | Objetivo de ganancia | Lengo la faida |
| prop.on_track | On Track | في المسار الصحيح | En bonne voie | En buen camino | Katika mwelekeo |
| wallet.balance | Total Balance | الرصيد الإجمالي | Solde total | Saldo total | Salio la jumla |
| ai.placeholder | Ask AI anything… | اسأل مساعد الذكاء الاصطناعي… | Demandez à l'IA… | Pregunta a la IA… | Uliza AI chochote… |
| kyc.pending | KYC Pending | التحقق معلق | KYC en attente | KYC pendiente | KYC inasubiri |
| common.confirm | Confirm | تأكيد | Confirmer | Confirmar | Thibitisha |
| common.cancel | Cancel | إلغاء | Annuler | Cancelar | Ghairi |
Implementation
i18n Architecture
// lib/i18n/index.ts — Core i18n system import { createContext, useContext, useState, useEffect } from 'react'; import en from './locales/en.json'; import ar from './locales/ar.json'; import fr from './locales/fr.json'; import es from './locales/es.json'; import sw from './locales/sw.json'; export type Locale = 'en' | 'ar' | 'fr' | 'es' | 'sw'; export const LOCALES: Record<Locale, { name: string; native: string; flag: string; dir: 'ltr' | 'rtl' }> = { en: { name: 'English', native: 'English', flag: '🇬🇧', dir: 'ltr' }, ar: { name: 'Arabic', native: 'العربية', flag: '🇸🇦', dir: 'rtl' }, fr: { name: 'French', native: 'Français', flag: '🇫🇷', dir: 'ltr' }, es: { name: 'Spanish', native: 'Español', flag: '🇪🇸', dir: 'ltr' }, sw: { name: 'Swahili', native: 'Kiswahili', flag: '🇰🇪', dir: 'ltr' }, }; const translations = { en, ar, fr, es, sw }; type I18nContextType = { locale: Locale; t: (key: string, params?: Record<string, string | number>) => string; setLocale: (locale: Locale) => void; dir: 'ltr' | 'rtl'; isRTL: boolean; }; const I18nContext = createContext<I18nContextType>({} as I18nContextType); export function I18nProvider({ children }: { children: React.ReactNode }) { const [locale, setLocaleState] = useState<Locale>(() => { // Detect browser language or stored preference const stored = localStorage.getItem('guro_locale') as Locale; const browser = navigator.language.split('-')[0] as Locale; return stored || (Object.keys(LOCALES).includes(browser) ? browser : 'en'); }); const setLocale = (newLocale: Locale) => { setLocaleState(newLocale); localStorage.setItem('guro_locale', newLocale); document.documentElement.lang = newLocale; document.documentElement.dir = LOCALES[newLocale].dir; // Update font for Arabic document.body.style.fontFamily = newLocale === 'ar' ? "'Noto Sans Arabic', sans-serif" : "'Outfit', sans-serif"; }; useEffect(() => { setLocale(locale); }, []); const t = (key: string, params?: Record<string, string | number>) => { const dict = translations[locale] as Record<string, string>; let str = dict[key] || translations.en[key as keyof typeof translations.en] || key; if (params) { Object.entries(params).forEach(([k, v]) => { str = str.replace(new RegExp(`{{${k}}}`, 'g'), String(v)); }); } return str; }; return ( <I18nContext.Provider value={{ locale, t, setLocale, dir: LOCALES[locale].dir, isRTL: LOCALES[locale].dir === 'rtl' }}> {children} </I18nContext.Provider> ); } export const useI18n = () => useContext(I18nContext);
// locales/ar.json — Arabic Translation (full excerpt) { // Navigation "nav.dashboard": "لوحة التحكم", "nav.trade": "تداول الأسواق", "nav.positions": "المراكز المفتوحة", "nav.history": "سجل التداول", "nav.watchlist": "قائمة المتابعة", "nav.wallet": "المحفظة", "nav.prop_challenge": "تحدي التمويل", "nav.copy_trading": "تداول النسخ", "nav.ai_assistant": "مساعد الذكاء الاصطناعي", "nav.settings": "الإعدادات", "nav.sign_out": "تسجيل الخروج", // Dashboard "dashboard.greeting": "صباح الخير، {{name}} 👋", "dashboard.markets_open": "الأسواق مفتوحة", "dashboard.balance": "الرصيد", "dashboard.open_pnl": "الربح والخسارة المفتوح", "dashboard.open_trades": "الصفقات المفتوحة", "dashboard.prop_progress": "تقدم تحدي التمويل", "dashboard.deposit": "إيداع", "dashboard.trade_now": "تداول الآن", "dashboard.view_all": "عرض الكل", "dashboard.edit": "تعديل", "dashboard.open_positions": "المراكز المفتوحة", "dashboard.watchlist": "قائمة المتابعة", // Trading "trade.buy": "شراء", "trade.sell": "بيع", "trade.lot_size": "حجم العقد", "trade.stop_loss": "وقف الخسارة", "trade.take_profit": "جني الأرباح", "trade.leverage": "الرافعة المالية", "trade.margin": "الهامش المطلوب", "trade.spread": "الفارق السعري", "trade.commission": "العمولة", "trade.execute_buy": "تنفيذ أمر الشراء", "trade.execute_sell": "تنفيذ أمر البيع", // AI "ai.title": "مساعد أبيكس الذكي", "ai.online": "متصل — يراقب حسابك", "ai.placeholder": "اسأل مساعد الذكاء الاصطناعي أي شيء…", "ai.analyse": "تحليل", "ai.best_setup": "أفضل إعداد", "ai.my_risk": "مستوى المخاطرة", "ai.news_today": "أخبار اليوم", // Prop Challenge "prop.title": "تحدي التمويل", "prop.profit_target": "هدف الربح", "prop.daily_loss": "حد الخسارة اليومية", "prop.max_drawdown": "الحد الأقصى للسحب", "prop.trading_days": "أيام التداول", "prop.on_track": "في المسار الصحيح", "prop.request_payout": "طلب السحب", // Wallet "wallet.title": "محفظتي", "wallet.deposit": "إيداع", "wallet.withdraw": "سحب", "wallet.total_balance": "الرصيد الإجمالي", "wallet.equity": "حقوق الملكية", "wallet.margin_used": "الهامش المستخدم", "wallet.free_margin": "الهامش المتاح", // KYC "kyc.pending": "التحقق من الهوية معلق", "kyc.verified": "تم التحقق ✓", "kyc.complete": "إكمال التحقق من الهوية", // Common "common.loading": "جار التحميل…", "common.error": "حدث خطأ", "common.success": "تم بنجاح", "common.cancel": "إلغاء", "common.confirm": "تأكيد", "common.back": "رجوع", "common.next": "التالي", "common.save": "حفظ", "common.close": "إغلاق" }
/* styles/rtl.css — RTL Layout Overrides */ /* ── Base RTL document ── */ [dir="rtl"] { text-align: right; font-family: 'Noto Sans Arabic', 'Outfit', sans-serif; } /* ── Flex direction reversal ── */ [dir="rtl"] .flex-row { flex-direction: row-reverse; } [dir="rtl"] .nav-items { flex-direction: row-reverse; } [dir="rtl"] .card-header { flex-direction: row-reverse; } [dir="rtl"] .stat-row { flex-direction: row-reverse; } /* ── Sidebar ── */ [dir="rtl"] #sidebar { left: auto; right: 0; border-right: none; border-left: 1px solid var(--bdr3); transform: translateX(105%); } [dir="rtl"] #sidebar.open { transform: translateX(0); } [dir="rtl"] #main { margin-left: 0; margin-right: var(--sideW, 0); } /* ── Active border indicator (left → right) ── */ [dir="rtl"] .wl-item.active { border-left: none; border-right: 2px solid var(--gold); } /* ── Margin/padding mirroring ── */ [dir="rtl"] .pos-pl, [dir="rtl"] .wl-right, [dir="rtl"] .hist-right { margin-left: 0; margin-right: auto; } [dir="rtl"] .pl-indent { padding-left: 0; padding-right: 16px; } [dir="rtl"] .ml-auto { margin-left: 0; margin-right: auto; } /* ── Progress bars (visual only, no direction change) ── */ [dir="rtl"] .rule-bar, [dir="rtl"] .pt-bar { direction: ltr; } /* ── Arabic number formatting ── */ [dir="rtl"] .mono-number { font-family: 'JetBrains Mono', monospace; unicode-bidi: plaintext; } /* ── Bottom nav ── */ [dir="rtl"] #botnav { flex-direction: row-reverse; } /* ── Form inputs ── */ [dir="rtl"] input, [dir="rtl"] textarea, [dir="rtl"] select { text-align: right; direction: rtl; } /* ── Exception: numbers always LTR ── */ [dir="rtl"] .price-val, [dir="rtl"] .pnl-val, [dir="rtl"] .account-id { direction: ltr; unicode-bidi: embed; } /* ── Toast messages ── */ [dir="rtl"] .toast { font-family: 'Noto Sans Arabic', sans-serif; } /* ── Chevrons / arrows direction flip ── */ [dir="rtl"] .chevron-right::after { content: '←'; } [dir="rtl"] .chevron-left::after { content: '→'; } [dir="rtl"] .back-arrow svg { transform: scaleX(-1); } /* ── Next.js App Router — next-intl config ── */ // next.config.ts import createNextIntlPlugin from 'next-intl/plugin'; const withNextIntl = createNextIntlPlugin('./i18n.ts'); export default withNextIntl({ i18n: { locales: ['en', 'ar', 'fr', 'es', 'sw'], defaultLocale: 'en', }, });
// lib/ai/translate.ts — AI-powered dynamic translation // APEX AI responses are dynamically generated in user's language import Apex from '@apex-ai/sdk'; import { type Locale, LOCALES } from '../i18n'; const client = new Apex(); // Generate AI trading analysis in user's language export async function getLocalizedAIAnalysis( pair: string, data: object, locale: Locale ): Promise<string> { const lang = LOCALES[locale].name; const isRTL = LOCALES[locale].dir === 'rtl'; const systemPrompt = ` You are APEX, the AI trading assistant for Guro Markets. IMPORTANT: Respond ENTIRELY in ${lang}. ${isRTL ? 'Use proper RTL Arabic script. Use Arabic financial terminology.' : ''} Be concise (2-3 sentences max). Use the same professional tone. Numbers and tickers (XAU/USD, etc.) stay in their original format. `; const response = await client.messages.create({ model: 'apex-core-v2', max_tokens: 256, system: systemPrompt, messages: [{ role: 'user', content: `Analyse this trading data and give a brief recommendation: ${JSON.stringify(data)}` }] }); return response.content[0].type === 'text' ? response.content[0].text : ''; } // Batch translate static strings (for server-side pre-rendering) export async function translateStrings( strings: string[], targetLocale: Locale ): Promise<Record<string, string>> { if (targetLocale === 'en') { return Object.fromEntries(strings.map(s => [s, s])); } const lang = LOCALES[targetLocale].name; const response = await client.messages.create({ model: 'apex-core-v2', max_tokens: 2048, messages: [{ role: 'user', content: `Translate these UI strings to ${lang}. Return JSON only. Preserve {{variables}} exactly. Financial/trading terms use industry-standard ${lang} terminology. Strings: ${JSON.stringify(strings)}` }] }); try { const text = response.content[0].type === 'text' ? response.content[0].text : '{}'; return JSON.parse(text.replace(/```json|```/g, '')); } catch { return Object.fromEntries(strings.map(s => [s, s])); } }