How We Built a 10-Language Bulk QR Generator (And Handled RTL Layouts)
When we launched the RahaLune Bulk QR Code Generator, it was a fully functional, client-side React application capable of generating up to 500 custom QR codes from a CSV file. But there was a problem. It was English-on
When we launched the RahaLune Bulk QR Code Generator, it was a fully functional, client-side React application capable of generating up to 500 custom QR codes from a CSV file.
But there was a problem. It was English-only. For a tool designed to help global businesses, event planners, and inventory managers, this was a massive barrier.
Today, we rolled out a massive update. The entire Bulk Generator is now natively translated into 10 languages, complete with full Right-to-Left (RTL) layout support.
Here is a look at how we handled the localization entirely on the client-side.
The Translation Architecture
Since RahaLune is a 100% client-side app, we didn't want to rely on an API to fetch translations. We wanted the site to remain incredibly fast, even if the user switched languages multiple times.
We used standard JSON files for each language (en.json, fr.json, ar.json, etc.). When the user selects a language from the header dropdown, or visits a localized URL (like ?lang=fr), the app dynamically imports the corresponding JSON file and updates the React context.
This keeps the initial bundle size small and ensures that the translation happens instantly.
Handling the RTL Layout Challenge
Supporting Arabic and Urdu wasn't just about translating the textβit required a complete layout flip.
If you are building an app with RTL support, the golden rule is to avoid hardcoding directional CSS. Instead of using margin-left or padding-right, you should use CSS logical properties:
-
margin-inline-startinstead ofmargin-left -
padding-inline-endinstead ofpadding-right
We also dynamically update the <html> tag based on the selected language to trigger the browser's native RTL rendering:
javascript
document.documentElement.setAttribute('dir', currentLanguage === 'ar' || currentLanguage === 'ur' ? 'rtl' : 'ltr');
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.