I Spent a Week Adding Arabic to Our React Native App. Here’s What I Wish I’d Known.
Every shortcut you take with strings becomes a debt. The day your app crosses a border, the bill comes due.
I Spent a Week Adding Arabic to Our React Native App. Here’s What I Wish I’d Known.
Every shortcut you take with strings becomes a debt. The day your app crosses a border, the bill comes due.
The bug report came in at 9:47 PM. A user in Dubai had downloaded our app, switched the language to Arabic, and sent a screenshot of what looked like a UI thrown into a blender.
The back button was on the wrong side. A chevron pointed nowhere. Numbers were left-aligned in a sea of right-aligned text. And the worst part: most of the strings were still in English, because at some point during a sprint we had decided “we’ll add i18n later.”
Later had arrived. And it was expensive.
This is what I learned about internationalization the hard way, so you don’t have to.
i18n Isn’t a Feature. It’s an Architectural Decision.
The first lesson is uncomfortable.
The day you decide to support multiple languages, every line of code you’ve ever written becomes either ready or unready. If your strings are hardcoded inside JSX components, you’re not “adding Spanish” — you’re rewriting your app to use a translation function, then adding Spanish.
This is why the developers I’ve met who run successful global apps all do the same thing: they pretend their MVP is multi-language from day one, even when it’s not. Every string goes through a translation function. Every layout uses logical properties. Every date is formatted through Intl.
It costs maybe an extra hour during initial setup. It saves you a week per language you add later.
You Cannot Build Sentences With Concatenation
The first version of our greeting was something like:
t('hello') + ', ' + user.name + '!'
It read fine in English. In Japanese, the name should come before the greeting. In Arabic, the entire sentence reads right-to-left. Concatenation forces English word order onto every language.
The fix is interpolation:
t('greeting', { name: user.name })
With "greeting": "{{name}}さん、こんにちは!" in your Japanese translation file. The translator gets to rearrange the sentence freely. You stop accidentally exporting English grammar to the world.
Pluralization Will Humble You
I once wrote count === 1 ? 'item' : 'items' and felt clever about it.
Then I learned that Russian has three plural forms. Arabic has six. Polish has its own rules. Welsh has rules so weird they’re considered a benchmark for translation libraries.
You cannot solve this with a ternary. You use ICU MessageFormat or i18next plural rules, and let the library pick the correct form based on the active locale’s CLDR rules.
Every other approach is wrong, and you’ll find out which way it’s wrong from a user, not your test suite.
RTL Isn’t About Reversing Text — It’s About Mirroring the UI
Arabic, Hebrew, Persian, and Urdu all read right-to-left. Supporting them isn’t reversing text. It’s mirroring the entire UI.
Buttons move from the right edge to the left. Icons that point “forward” now point in the opposite direction. Padding that was on the left needs to be on the right.
React Native gives you logical properties — marginStart, paddingEnd — that flip automatically when RTL is enabled. If you've been writing marginLeft your entire career, you have to retrain your fingers. The ones who do this from day one save themselves a refactor that touches every component.
There’s one cruelty here: switching between LTR and RTL requires an app restart in React Native. The layout engine cannot toggle direction at runtime. So your language switcher needs a confirmation dialog: “This will restart the app.”
Plan for that UX, because the alternative is a half-mirrored UI and a five-star review that drops to one.
Your Translation File Is a Living Artifact
A translation file is not a one-time deliverable.
Every feature adds keys. Every release needs those keys translated before it ships. The teams that get this right have a workflow:
- Developer adds an English key
- CI catches missing translations in other locales
- A service like Crowdin or Lokalise routes the keys to translators
- CI pulls the latest translations before each release
Without this, you ship a release with three untranslated strings and don’t notice for a month.
What I’d Do Differently
If I were starting from scratch, I’d treat i18n like authentication or analytics — something you set up before you write your second screen. The cost is rounding error. The cost of not doing it is a week of debugging at 9:47 PM with a bug report from Dubai.
There’s a tool I’ve been playing with called RapidNative that generates React Native code from plain English prompts, and it scaffolds translation keys into every component by default. For new projects, it removes the “we’ll add i18n later” tax entirely.
But the tool isn’t really the point.
The point is: every shortcut you take with strings becomes a debt. Every shortcut you take with layout becomes a debt. The day your app crosses a border, the bill comes due.
Pay it now, while it’s small.
If this resonated, give it a clap and follow for more notes from the trenches of mobile development. What’s the most painful i18n bug you’ve shipped? Tell me in the comments.
Originally published at https://hashnode on May 8, 2026.
메타데이터
- post_id
- cd2ffa29afc8
- slug
- i-spent-a-week-adding-arabic-to-our-react-native-app-heres-what-i-wish-i-d-known-cd2ffa29afc8
- url
- https://medium.com/@famitha_30242/i-spent-a-week-adding-arabic-to-our-react-native-app-heres-what-i-wish-i-d-known-cd2ffa29afc8
- canonical_url
- https://medium.com/@famitha_30242/i-spent-a-week-adding-arabic-to-our-react-native-app-heres-what-i-wish-i-d-known-cd2ffa29afc8
- author_url
- https://medium.com/@famitha_30242
- status
- ok
- fetched_at
- 2026-06-09 15:37:30