i18n (Regional Locales)
Locales
// i18n/routing.ts
locales: ['en-ae', 'ar-ae', 'en-gl', 'ar-gl']
defaultLocale: 'en-ae'
// *-ae = UAE local shipping, *-gl = international
Messages: en-ae/en-gl → messages/en.json, ar-* → messages/ar.json
Navigation (mandatory)
import { Link, useRouter, usePathname, redirect } from '@/i18n/navigation';
// NEVER raw next/link or next/navigation for user routes
Server
import { setRequestLocale, getTranslations } from 'next-intl/server';
setRequestLocale(locale);
const t = await getTranslations({ locale, namespace: 'checkout' });
Client
import { useTranslations, useLocale } from 'next-intl';
const t = useTranslations('Auth');
const locale = useLocale(); // "en-ae"
RTL
<html dir={locale.includes('ar') ? 'rtl' : 'ltr'}>
Bilingual Data (from API)
const name = locale.includes('ar') ? product.name_ar : product.name_en;
// or getLang(locale) from utils/locale.ts
UI strings → JSON messages. Entity content → _en/_ar API fields.
Language Switcher
Swap language part only: en-ae ↔ ar-ae, en-gl ↔ ar-gl. Preserve search params (tracking).
Region Switcher
en-ae ↔ en-gl via country config store. May trigger cart conflict check.
Path Helper
withLocalePath('/products/foo', 'en-gl') // → "/en-gl/products/foo"
Middleware
Legacy /en → /en-ae. Root / geo redirect. next-intl routing after auth checks.