Translation Usage
Practical translation usage for server and client code.
What It Does
Shows the preferred usage patterns for react-i18next in this codebase.
When To Use
- Translating components and metadata.
- Passing dynamic values into translated strings.
Prerequisites
- i18n configured and provider mounted.
This page describes the standard kit integration path; adapt app-specific paths and config names when your project differs.
How To Use
useTranslation in client components
'use client'; import { Trans, useTranslation } from 'react-i18next'; export function Title() { const { t, i18n: { language }, } = useTranslation('dashboard'); return ( <div className="space-y-2"> <h1>{t('home.title')}</h1> <p>{t('activeLanguage', { language })}</p> <Trans i18nKey="auth.signUpTitle" ns="dashboard" components={{ strong: <strong className="font-semibold" /> }} /> </div> ); }
useTranslation is a client hook, but this monorepo also supports server-side translations through getServerI18n to avoid waiting for client hydration.
Server components and metadata
import { getServerI18n } from '~/lib/i18n.server';
export async function generateMetadata() {
const { t } = await getServerI18n();
return { title: t('dashboard:meta.home') };
}
export default async function DashboardPage() {
const { t } = await getServerI18n();
return <h1>{t('dashboard:home.title')}</h1>;
}Interpolation and dynamic values
{
"welcome": "Hello {{name}}",
"summary": "{{count}} new notifications",
"authorLine": "Written by {{author.name}}"
}t('welcome', { name: 'Arnaud' });
t('summary', { count: 3 });
t('authorLine', { author: { name: 'Arnaud' } });Avoid manual concatenation such as t('welcome') + userName. Keep variables inside interpolation so translators control word order and grammar.
Rich text with custom tags
{
"legal.notice": "By continuing, you accept our <terms>Terms of Service</terms>."
}import { Trans } from 'react-i18next';
<Trans
i18nKey="legal.notice"
ns="dashboard"
components={{
terms: <a href="/terms" className="underline" />,
}}
/>Translations in constants and config objects
When a list/config needs translated labels, define a factory function that receives t instead of translating at module load time.
Before:
const NAV_ITEMS = [{ key: 'home', label: 'Home' }];After:
import type { TFunction } from 'i18next';
export const getNavItems = (t: TFunction<'dashboard'>) => [
{ key: 'home', label: t('navigation.home') },
{ key: 'settings', label: t('navigation.settings') },
{ key: 'profile', label: t('navigation.profile') },
];Namespace usage tips
- Prefer
useTranslation('namespace')in client components for short keys (t('home.title')). - On server code, namespace-qualified keys (
t('dashboard:home.title')) are explicit and safe. - If
t(...)returns the key itself, first verify that the namespace is registered inconfig/i18n.config.tsand locale JSON exists.
MCP Context
capability: i18n_usage_patterns
entrypoints:
- react-i18next useTranslation
- apps/*/lib/i18n.server.ts
inputs:
- namespace_key
- interpolation_values
outputs:
- localized_string
constraints:
- namespace key must exist in loaded resources
side_effects:
- noneAgent Recipe
- Use
useTranslationin client components. - Use
getServerI18nin server functions/components. - Use
Transfor rich text tags/components in translated strings. - Prefer interpolation over string concatenation.
- Build translated constants through factory functions that accept
t.
Troubleshooting
- If
t(...)returns keys, namespace probably not loaded. - If server text is wrong language, verify proxy and header setup.
- If rich text tags render as plain text, verify
Transis used and component tags match translation placeholders.
Related
i18next integration pattern used across web apps.
Reusable language switcher component from @kit/i18n.
How is this guide?
Last updated on 3/23/2026