Skip to main content
AI
7 min read
January 16, 2026

AI-Assisted i18n: Localizing Your React App 10x Faster

The Localization Bottleneck

Segev Sinay

Segev Sinay

Frontend Architect

Share:

The Localization Bottleneck

Internationalization is one of those tasks that every team knows they should do early but always postpones until a client asks for it. Then it becomes a nightmare: hundreds of hardcoded strings scattered across dozens of components, date formats that assume US locale, RTL layout support that was never considered, and a deadline that is always too tight.

I have localized React applications for Hebrew, Arabic, Spanish, German, and Japanese markets. The manual approach - finding every string, extracting it to a key, translating it, testing every page - used to take two to four weeks for a medium-sized app. With AI assistance, I now do it in two to three days.

Here is the exact process.

Step 1: Set Up the i18n Infrastructure (10 Minutes)

Install react-i18next, the industry standard for React internationalization:

npm install react-i18next i18next i18next-browser-languagedetector i18next-http-backend

Create the configuration:

// src/i18n/config.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import HttpBackend from 'i18next-http-backend';

i18n
  .use(HttpBackend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    supportedLngs: ['en', 'he', 'es', 'de'],
    defaultNS: 'common',
    ns: ['common', 'dashboard', 'settings', 'auth'],
    interpolation: {
      escapeValue: false, // React already escapes
    },
    backend: {
      loadPath: '/locales/{{lng}}/{{ns}}.json',
    },
    detection: {
      order: ['querystring', 'localStorage', 'navigator'],
      caches: ['localStorage'],
    },
  });

export default i18n;

Import it in your entry file:

// src/main.tsx
import './i18n/config';

Step 2: Extract All Hardcoded Strings (30 Minutes)

This is the most tedious part of localization, and where AI saves the most time:

Scan the entire src/ directory and find every hardcoded user-facing string.

Include:
- JSX text content: <h1>Welcome back</h1>
- Attribute strings: placeholder="Enter your email"
- Template literals with user text: `Hello, ${name}!`
- Error messages: toast.error("Something went wrong")
- Button labels, form labels, tooltips, aria-labels
- Validation messages: "Email is required"

Exclude:
- CSS class names
- Console.log messages
- Internal variable names
- API endpoint URLs
- TypeScript type definitions

For each string found:
1. File path and line number
2. The original string
3. A suggested i18n key following the pattern: namespace.section.description
4. Whether it contains interpolation variables

Output as a CSV: file, line, original, key, hasInterpolation

Example:
src/pages/Dashboard.tsx, 45, "Welcome back", dashboard.header.welcomeBack, false
src/pages/Dashboard.tsx, 52, "You have {count} notifications", dashboard.header.notificationCount, true

On a typical 50-component app, this finds 200-400 strings. Doing this manually takes a full day. AI does it in minutes.

Step 3: Generate Translation Files (15 Minutes)

Take the extracted strings and generate the English base translation file:

Using the extracted strings list, generate the translation JSON files.

Create:
1. public/locales/en/common.json - shared strings (nav, footer, buttons, errors)
2. public/locales/en/dashboard.json - dashboard-specific strings
3. public/locales/en/settings.json - settings page strings
4. public/locales/en/auth.json - login, signup, password reset strings

Format:
{
  "header": {
    "welcomeBack": "Welcome back",
    "notificationCount": "You have {{count}} notifications",
    "notificationCount_one": "You have {{count}} notification",
    "notificationCount_other": "You have {{count}} notifications"
  }
}

Requirements:
- Use nested keys for organization (max 3 levels deep)
- Handle pluralization with i18next plural suffix (_one, _other, _zero)
- Use {{variable}} syntax for interpolation
- Group by page section, not by component

Step 4: Generate Translations for Target Languages (20 Minutes)

This is where AI truly shines. Professional translation costs $0.10-0.20 per word. For 400 strings averaging 5 words each, that is $200-400 per language. AI translations are not perfect, but they are 85-90% production-ready:

Translate the English translation files to Hebrew (he).

Requirements:
1. Keep all JSON keys in English (only translate values)
2. Keep all {{interpolation}} variables unchanged
3. Handle pluralization rules for Hebrew (_one, _two, _other)
4. Handle grammatical gender where relevant
5. Keep brand names, technical terms, and product names in English
6. Use natural, conversational Hebrew - not overly formal
7. For UI elements (buttons, labels), keep translations concise
8. RTL: no special handling needed in translation files, just natural Hebrew

Create: public/locales/he/common.json, dashboard.json, settings.json, auth.json

Also flag any strings that:
- Are ambiguous without context (the same English word can mean different things)
- Have cultural references that may not translate well
- Need different lengths that might break the UI layout

Repeat for each target language. For languages I do not speak, I have a native speaker review the AI translations. They typically need to correct 10-15% of strings - mostly nuance and tone, not meaning.

Step 5: Replace Strings in Components (30 Minutes)

Now automate the actual code changes:

Read src/pages/Dashboard.tsx and replace all hardcoded strings with
i18next translation calls.

Rules:
1. Import useTranslation: import { useTranslation } from 'react-i18next';
2. Add const { t } = useTranslation('dashboard'); at the top of the component
3. Replace strings:
   - "Welcome back" -> {t('header.welcomeBack')}
   - "You have 5 notifications" -> {t('header.notificationCount', { count: 5 })}
   - placeholder="Search..." -> placeholder={t('common:search.placeholder')}
4. For strings with HTML: use Trans component
   - "Read our <a>terms</a>" -> <Trans i18nKey="footer.terms" components={{ a: <Link to="/terms" /> }} />
5. Keep the same visual layout - do not change any styling or structure
6. If a component uses strings from multiple namespaces, import them:
   const { t } = useTranslation(['dashboard', 'common']);

Show me the complete updated file.

Run this for each component file. I typically batch 3-5 small components per prompt and handle large components individually.

Step 6: Handle RTL Layout (15 Minutes)

For RTL languages like Hebrew and Arabic, you need layout adjustments:

Scan the entire src/ directory for CSS/Tailwind patterns that need RTL support:

1. Fixed directional values:
   - margin-left, margin-right -> margin-inline-start, margin-inline-end
   - padding-left, padding-right -> padding-inline-start, padding-inline-end
   - left, right -> inset-inline-start, inset-inline-end
   - text-align: left -> text-align: start

2. Tailwind classes:
   - ml-4 -> ms-4 (margin-start)
   - pr-2 -> pe-2 (padding-end)
   - left-0 -> start-0
   - text-left -> text-start

3. Flexbox/Grid direction:
   - Items that should reverse in RTL
   - Icons that have directional meaning (arrows, chevrons)

4. Components that need special RTL handling:
   - Navigation breadcrumbs
   - Progress bars
   - Sliders and carousels

For each issue, show the file, current code, and the RTL-safe replacement.

Step 7: Test Every Language (10 Minutes)

Add a language switcher for development and QA:

// src/components/dev/LanguageSwitcher.tsx
import { useTranslation } from 'react-i18next';

export function LanguageSwitcher() {
  const { i18n } = useTranslation();

  return (
    <div className="fixed bottom-4 right-4 flex gap-2 z-50">
      {['en', 'he', 'es', 'de'].map((lng) => (
        <button
          key={lng}
          onClick={() => i18n.changeLanguage(lng)}
          className={`px-3 py-1 rounded text-sm ${
            i18n.language === lng ? 'bg-blue-600 text-white' : 'bg-gray-200'
          }`}
        >
          {lng.toUpperCase()}
        </button>
      ))}
    </div>
  );
}

Then use Claude Code to check for layout issues:

With the app running in Hebrew (RTL), check for common layout issues:

1. Text overflow - Hebrew strings are often longer than English
2. Truncated labels - buttons and form labels cut off
3. Misaligned icons - icons that should flip in RTL
4. Number formatting - dates, currencies, phone numbers
5. Form validation messages - do they display correctly in RTL?

For each issue found, suggest the CSS fix.

Results I Have Seen

Medium-sized SaaS app (52 components, ~350 strings):

  • Manual localization estimate: 3-4 weeks
  • AI-assisted localization: 2.5 days
  • Translation accuracy (reviewed by native speakers): 87% usable as-is, 13% needed minor edits
  • Cost savings: ~$1,200 in professional translation fees for the first pass

The AI does not replace professional translators for final quality, but it gets you 85-90% of the way there in a fraction of the time. For MVP and beta launches, that is more than enough.

AI
React
Productivity
TypeScript
Testing
i18n
Technical Leadership
Prompt Engineering

Related Articles

Get started

Ready to Work Differently with AI?

I work with a small number of organizations at a time. Reach out to discuss your workflows and see if there’s a fit.

Send a Message