FeaturesTranslations
PreviousNext

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.

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> ); }

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' } });

Rich text with custom tags

public/locales/en/dashboard.json
{
  "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 in config/i18n.config.ts and 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:
  - none

Agent Recipe

  1. Use useTranslation in client components.
  2. Use getServerI18n in server functions/components.
  3. Use Trans for rich text tags/components in translated strings.
  4. Prefer interpolation over string concatenation.
  5. 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 Trans is used and component tags match translation placeholders.

How is this guide?

Last updated on 3/23/2026