The namespace parameter in the useTranslation hook helps you access a specific section of your translations:
// Access translations under web.contact.formconst { t } = useTranslation('web.contact.form');// Now you can use t('fieldName') instead of t('web.contact.form.fieldName')t('name') // -> "Name"t('email') // -> "Email"
You can use different namespaces in different components based on the section of translations they need:
// In a navigation componentconst { t } = useTranslation('web.header');// In a footer componentconst { t } = useTranslation('web.footer');
You can include dynamic values in your translations:
// Translation: "Hello, {name}!"const { t } = useTranslation('web.greeting');// Pass values as an objectt('welcome', { name: user.name }) // -> "Hello, John!"
For date and number formatting:
// Translation: "Last updated on {date}"const { t } = useTranslation('web.common');// Format date according to the current localeconst formattedDate = new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'long', day: 'numeric'}).format(new Date());t('lastUpdated', { date: formattedDate })
You can create a language switcher component to allow users to change the language:
// components/LanguageSwitcher.tsx'use client';import Link from 'next/link';import { usePathname } from 'next/navigation';import { i18nConfig } from '@repo/internationalization/i18nConfig';import { useTranslation } from '@repo/internationalization/useTranslation';// Map of locale codes to their display namesconst localeNames: Record<string, string> = { en: 'English', tr: 'Türkçe', es: 'Español', de: 'Deutsch'};export default function LanguageSwitcher() { const pathname = usePathname(); const { t } = useTranslation('web.common'); // Function to get the path for a different locale const getLocalePath = (locale: string) => { const segments = pathname.split('/'); const currentLocale = segments[1]; // Check if the current path already has a locale if (i18nConfig.locales.includes(currentLocale)) { segments[1] = locale; return segments.join('/'); } // If no locale in the path, add it return `/${locale}${pathname}`; }; return ( <div className="language-switcher"> <span className="language-label">{t('language')}:</span> <ul className="language-list"> {i18nConfig.locales.map((locale) => ( <li key={locale}> <Link href={getLocalePath(locale)} className={pathname.startsWith(`/${locale}/`) ? 'active' : ''} > {localeNames[locale] || locale.toUpperCase()} </Link> </li> ))} </ul> </div> );}
Split large Client Components into smaller ones and use the appropriate namespace for each component to keep translations organized.
Use TypeScript for Type Safety
Define types for your translations to get better IDE support:
// Define types for your translationstype ContactFormTranslations = { name: string; email: string; message: string; submit: string; // Add more fields as needed};// Use type assertion for better type checkingconst { t } = useTranslation<ContactFormTranslations>('web.contact.form');
Handle Missing Translations
Always provide fallbacks for translations that might be missing:
// Use optional chaining and nullish coalescing{t('specialField') ?? t('defaultField')}