--- name: localization-engineer description: Expert in internationalization (i18n), multi-language support, and localization version: 1.0.0 tags: [i18n, localization, translation, multilingual, internationalization] --- # Localization Engineer Skill I help you build multilingual applications with proper internationalization (i18n) and localization (l10n) support. ## What I Do **Internationalization:** - Multi-language text content - Date/time formatting - Number and currency formatting - Right-to-left (RTL) support **Localization:** - Translation management - Language detection - Language switching - Locale-specific content ## Next.js Internationalization ### Setup with next-intl ```bash npm install next-intl ``` ```typescript // i18n/request.ts import { getRequestConfig } from 'next-intl/server' export default getRequestConfig(async ({ locale }) => ({ messages: (await import(`../messages/${locale}.json`)).default })) ``` ```typescript // middleware.ts import createMiddleware from 'next-intl/middleware' export default createMiddleware({ locales: ['en', 'es', 'fr', 'de', 'ja'], defaultLocale: 'en' }) export const config = { matcher: ['/((?!api|_next|.*\\..*).*)'] } ``` ### Translation Files ```json // messages/en.json { "common": { "welcome": "Welcome", "loading": "Loading...", "error": "Something went wrong" }, "navigation": { "home": "Home", "about": "About", "contact": "Contact" }, "auth": { "login": "Log in", "logout": "Log out", "signUp": "Sign up", "emailPlaceholder": "Enter your email", "passwordPlaceholder": "Enter your password" } } ``` ```json // messages/es.json { "common": { "welcome": "Bienvenido", "loading": "Cargando...", "error": "Algo salió mal" }, "navigation": { "home": "Inicio", "about": "Acerca de", "contact": "Contacto" }, "auth": { "login": "Iniciar sesión", "logout": "Cerrar sesión", "signUp": "Registrarse", "emailPlaceholder": "Ingrese su correo electrónico", "passwordPlaceholder": "Ingrese su contraseña" } } ``` --- ## Using Translations ### Client Component ```typescript 'use client' import { useTranslations } from 'next-intl' export function LoginForm() { const t = useTranslations('auth') return (
) } ``` ### Server Component ```typescript import { useTranslations } from 'next-intl' export default function HomePage() { const t = useTranslations('common') return ({format.dateTime(date, { dateStyle: 'full' })}
{/* Short date */}{format.dateTime(date, { dateStyle: 'short' })}
{/* Custom format */}{format.dateTime(date, { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' })}
{/* Relative time */}{format.relativeTime(date)}
{format.number(value)}
{/* Currency */}{format.number(value, { style: 'currency', currency: 'USD' })}
{/* Percentage */}{format.number(value / 100, { style: 'percent' })}
{/* Compact notation */}{format.number(value, { notation: 'compact' })}
{t('count', { count })}
} // count = 0: "No items" // count = 1: "1 item" // count = 5: "5 items" ``` --- ## RTL (Right-to-Left) Support ```typescript // app/[locale]/layout.tsx import { useLocale } from 'next-intl' const rtlLanguages = ['ar', 'he', 'fa'] export default function LocaleLayout({ children }) { const locale = useLocale() const isRTL = rtlLanguages.includes(locale) return ( {children} ) } ``` **RTL CSS:** ```css /* Automatically flips for RTL */ .container { margin-inline-start: 1rem; /* Use logical properties */ padding-inline-end: 1rem; } /* Manual RTL handling */ [dir='rtl'] .menu { left: auto; right: 0; } ``` --- ## Language Detection ```typescript // lib/detect-locale.ts export function detectUserLocale(): string { // 1. Check URL parameter const urlParams = new URLSearchParams(window.location.search) const urlLocale = urlParams.get('lang') if (urlLocale) return urlLocale // 2. Check localStorage const savedLocale = localStorage.getItem('preferredLocale') if (savedLocale) return savedLocale // 3. Check browser language const browserLocale = navigator.language.split('-')[0] return browserLocale // 4. Default return 'en' } ``` --- ## Translation with Variables ```json // messages/en.json { "welcome": "Welcome, {name}!", "itemsInCart": "You have {count} {count, plural, one {item} other {items}} in your cart", "priceDisplay": "Price: {price, number, ::currency/USD}" } ``` ```typescript 'use client' import { useTranslations } from 'next-intl' export function Greeting({ userName }: { userName: string }) { const t = useTranslations() return ({t('itemsInCart', { count: 3 })}
{t('priceDisplay', { price: 49.99 })}
{content[locale].description}