Check middleware configurationEnsure your middleware.ts file is correctly configured:
// middleware.tsimport { internationalizationMiddleware } from '@repo/internationalization/middleware';import { NextRequest } from 'next/server';export function middleware(request: NextRequest) { return internationalizationMiddleware(request);}export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],};
Verify matcher patternMake sure the matcher pattern is correct and doesn’t exclude your routes:
// Correct matcher pattern that excludes only static assets and API routesmatcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
Check for conflicting middlewareIf you have other middleware, make sure they don’t conflict with the internationalization middleware:
// Combining multiple middlewareexport function middleware(request: NextRequest) { // First try internationalization middleware const i18nResponse = internationalizationMiddleware(request); if (i18nResponse) { return i18nResponse; } // If no response from i18n middleware, try other middleware return otherMiddleware(request);}
Check TranslationProvider setupMake sure your client components are wrapped with the TranslationProvider:
// In a Server Componentimport { getDictionary } from '@repo/internationalization';import { TranslationProvider } from '@repo/internationalization/TranslationProvider';import ClientComponent from '@/components/ClientComponent';export default async function ServerComponent({ params }: { params: { locale: string } }) { const dictionary = await getDictionary(params.locale); return ( <TranslationProvider locale={params.locale} messages={dictionary}> <ClientComponent /> </TranslationProvider> );}
Verify namespace parameterCheck that you’re using the correct namespace in the useTranslation hook:
// In a Client Component'use client';import { useTranslation } from '@repo/internationalization/useTranslation';export default function ClientComponent() { // Make sure this namespace exists in your translations const { t } = useTranslation('web.header'); return <div>{t('home')}</div>;}
Check for React context issuesIf you’re using multiple providers, make sure they’re not interfering with each other:
Check language switcher implementationMake sure your language switcher correctly builds the URLs:
'use client';import Link from 'next/link';import { usePathname } from 'next/navigation';import { i18nConfig } from '@repo/internationalization/i18nConfig';export default function LanguageSwitcher() { const pathname = usePathname(); // 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"> {i18nConfig.locales.map((locale) => ( <Link key={locale} href={getLocalePath(locale)} className={pathname.startsWith(`/${locale}/`) ? 'active' : ''} > {locale.toUpperCase()} </Link> ))} </div> );}
Verify route structureEnsure your routes are properly structured with the locale parameter:
Add console logs to track the flow of translations:
// In a Server Componentconsole.log('Loading dictionary for locale:', params.locale);const dictionary = await getDictionary(params.locale);console.log('Dictionary loaded:', Object.keys(dictionary));// In a Client Component'use client';import { useTranslation } from '@repo/internationalization/useTranslation';export default function DebugComponent() { const { t } = useTranslation('web'); console.log('Translation function available:', !!t); console.log('Sample translation:', t('header.home')); return <div>{t('header.home')}</div>;}
Define proper types for your translationsCreate a type definition for your translations:
// types/translations.tsexport type Dictionary = { web: { header: { home: string; about: string; contact: string; // Add more keys as needed }; // Add more sections as needed }; // Add more namespaces as needed};
Use type assertions with the useTranslation hook
import { useTranslation } from '@repo/internationalization/useTranslation';import type { Dictionary } from '@/types/translations';// Use type assertionconst { t } = useTranslation<Dictionary['web']['header']>('web.header');
Optimize dictionary sizeSplit large dictionaries into smaller chunks:
// Load only the translations needed for this pageconst commonDictionary = await getDictionary(locale, 'common');const pageDictionary = await getDictionary(locale, 'home');
Use code splittingLoad translations only when needed:
// Use dynamic imports for translationsconst HomePageContent = dynamic(() => import('@/components/HomePageContent'), { loading: () => <LoadingSpinner />});
Memoize translation functionsUse memoization to prevent unnecessary re-renders:
const memoizedTranslation = useMemo(() => { return { title: t('title'), description: t('description'), // Add more translations as needed };}, [t]);
Error: useTranslation must be used within a TranslationProvider
Solution:Make sure your client component is wrapped with the TranslationProvider:
// In a Server Component<TranslationProvider locale={params.locale} messages={dictionary}> <ClientComponent /></TranslationProvider>
Check that you’re not using the hook in a Server Component:
// This will cause an error in a Server Component// Only use useTranslation in Client Components with 'use client' directiveconst { t } = useTranslation('web');
Error: Failed to load dictionary for locale: [locale]
Solution:Check that the dictionary file exists for the specified locale:
# Check if the file existsls -la dictionaries/[locale].json
If it doesn’t exist, create it:
# Create a new dictionary file by copying the English onecp dictionaries/en.json dictionaries/[locale].json
Then translate the content or run the translation script: