sodcalculator

10 Tech How-To

Fix Translation & Encoding Issues in Flutter & React

Guide 10-13026 · Updated · Step by step

This guide walks you through diagnosing and fixing inaccurate translations and character encoding problems in Flutter and React applications. You’ll learn how to identify the root causes—from missing locale files to UTF-8 mishandling—and apply practical fixes that work across both frameworks.

What You’ll Need

  • A Flutter or React project with translation files (JSON, ARB, or similar)
  • Access to your code editor and terminal
  • Basic familiarity with your framework’s localization setup
  • For Flutter: the intl package and flutter_localizations SDK
  • For React: react-i18next or react-intl (or similar)

Step-by-Step

  1. Confirm the encoding of your source files. Open your translation files (e.g., en.json, es.json) in a text editor that shows encoding (VS Code shows it in the status bar). Ensure they are saved as UTF-8 without BOM. If they are UTF-16 or ANSI, re-save them as UTF-8.
  2. Check the HTML meta charset (React). In your index.html, ensure you have <meta charset="UTF-8"> inside the <head>. Without it, browsers may guess the encoding, causing mojibake (e.g., ’ instead of ’).
  3. Set the correct locale in Flutter. In your MaterialApp, pass locale and supportedLocales explicitly. For example: locale: Locale('es'), supportedLocales: [Locale('en'), Locale('es')]. Also add localizationsDelegates: GlobalMaterialLocalizations.delegates.
  4. Verify your translation keys match. Inaccurate translations often happen because a key is missing or mistyped. Use a tool like i18next-parser (React) or flutter gen-l10n (Flutter) to generate key lists and catch mismatches.
  5. Handle pluralization and interpolation correctly. Instead of concatenating strings, use the built-in plural and interpolation syntax. In React i18next: t('item_count', {count: items.length}). In Flutter: Intl.plural(count, one: '1 item', other: '${count} items').
  6. Escape special characters in JSON. If your translation file is JSON, ensure quotes and backslashes are escaped. For example, "He said \"hello\"". A missing escape can break the entire file, causing fallback to default language.
  7. Test with a right-to-left (RTL) language. If you support Arabic or Hebrew, ensure your layout handles RTL. In Flutter, set Directionality automatically via localizationsDelegates. In React, set dir="rtl" on the <html> element when the locale is RTL.
  8. Use a fallback language. Configure a fallback locale so that missing translations don’t show raw keys. In React i18next: fallbackLng: 'en'. In Flutter, use localeResolutionCallback to fallback to English.
  9. Clear caches and rebuild. Sometimes old compiled bundles retain stale strings. Run flutter clean and rebuild, or clear your React build cache (rm -rf node_modules/.cache) and restart the dev server.
  10. Check for encoding issues in API responses. If translations come from a backend, ensure the API returns Content-Type: application/json; charset=utf-8. Also verify that your fetch/Axios call doesn’t force a wrong encoding.

Common Mistakes

  • Using single quotes in English contractions within single-quoted strings. For example, 'Don\'t' in JavaScript can break. Use double quotes or escape properly.
  • Forgetting to import locale delegates in Flutter. Without GlobalMaterialLocalizations.delegates, date and number formatting will be in English even if your strings are translated.
  • Mixing up language codes. Using es vs es-ES inconsistently can cause fallback failures. Pick a standard and stick to it.
  • Hardcoding strings in widgets/components. Always use the translation function; otherwise, they won’t update when language changes.
  • Ignoring BOM (Byte Order Mark). Some editors add a BOM, which can cause the first key to be read incorrectly. Use UTF-8 without BOM.

Tips

  • Use a translation management system (TMS) like Lokalise or Crowdin to keep translations in sync and avoid manual file edits.
  • Add a language switcher in development to quickly test all locales without changing code.
  • Write unit tests for your translation keys. For example, in Jest, check that every key in the default locale exists in other locales.
  • Use the Intl package’s NumberFormat and DateFormat in Flutter to localize numbers and dates automatically.
  • In React, use the Trans component for complex JSX inside translations, instead of string concatenation.

Troubleshooting

If text shows as question marks or boxes (□): This usually means the font doesn’t support the characters. In Flutter, add a font like Noto Sans that covers the script. In React, ensure your CSS font-family includes fallbacks for the target language.

If translations work in development but not in production: Check if your build process minifies or re-encodes files incorrectly. For React, ensure public folder files are copied as-is. For Flutter, run flutter build --release and inspect the bundle for the locale files.

If only some strings are translated: Verify the key names match exactly, including case and underscores. Use a search in your codebase to find where the key is used and compare with the translation file.

If the app crashes on startup after adding a locale: You may be missing the flutter_localizations dependency or the intl package. Run flutter pub add flutter_localizations --sdk=flutter and flutter pub add intl.

If the language doesn’t switch at runtime: In React, make sure you call i18n.changeLanguage(lng) and then re-render. In Flutter, use a StatefulWidget that rebuilds MaterialApp with the new locale.

Frequently Asked Questions

Why do accented characters show as ’ instead of ’?

This is a classic UTF-8 vs Latin-1 mismatch. The file is likely saved as Latin-1 but the browser interprets it as UTF-8 (or vice versa). Re-save the file as UTF-8 without BOM.

How do I add a new language to my Flutter app?

Create an ARB file (e.g., app_fr.arb) in your lib/l10n folder, run flutter gen-l10n, then add the locale to supportedLocales in your MaterialApp.

Can I use machine translation for my app?

Yes, but always have a human review it. Machine translations often miss context and cultural nuances, leading to inaccurate or offensive text.

Why does my React app show the key name instead of the translation?

This happens when the translation file fails to load or the key is missing. Check the browser console for errors, and ensure your JSON file is valid and placed in the correct public path.

Is it better to use ICU MessageFormat or simple strings?

ICU MessageFormat (used by react-intl and Flutter’s intl) is better for pluralization and gender, but it’s more complex. For simple apps, plain strings are fine, but you’ll need to handle plurals manually.

How do I handle languages that read right-to-left?

In Flutter, the localizationsDelegates automatically set the direction. In React, set dir="rtl" on the <html> element when the locale is RTL, and use a CSS reset that supports RTL.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →