Skip to main content
AI
7 min read
February 1, 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

Contact

Let’s Connect

Have a question or an idea? I’d love to hear from you.

Send a Message