Software Architecture
Building a Bilingual Full-Stack App in Sharjah
Learn to build a bilingual full-stack application using React 18 and Node.js 16, focusing on RTL and LTR layouts for the UAE market.
Creating a bilingual application is essential for the UAE market, particularly in Sharjah, where the creative economy is vibrant and communication needs are diverse. Arabic and English are the two primary languages, requiring developers to build applications that accommodate right-to-left (RTL) and left-to-right (LTR) layouts. This tutorial will guide you through the process by showcasing both common pitfalls and best practices.
The Wrong Way: Ignoring RTL Support
To illustrate, let's consider a simple React component that does not account for RTL layout:
import React from 'react';
const UserProfile = ({ user }) => {
return (
<div style={{ textAlign: 'left' }}>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
};
export default UserProfile;
In this example, the textAlign style is hardcoded. If a user views this profile in Arabic, the text will not align correctly. This can lead to a poor user experience, disengagement, and ultimately loss of customers.
The Right Way: Dynamic Layouts with CSS
To support both Arabic and English, we need to utilize the dir attribute in HTML alongside CSS for layout adjustments. We’ll modify the component to react to the direction set in a parent component:
Step 1: Modify the UserProfile Component
First, let’s update the UserProfile component to accept a dir prop:
import React from 'react';
const UserProfile = ({ user, dir }) => {
return (
<div dir={dir} style={{ textAlign: dir === 'rtl' ? 'right' : 'left' }}>
<h1>{user.name}</h1>
<p>{user.bio}</p>
</div>
);
};
export default UserProfile;
Step 2: Set the Direction in the Parent Component
Now, we need to handle direction in a parent component, for example, when rendering the UserProfile:
import React, { useState } from 'react';
import UserProfile from './UserProfile';
const App = () => {
const [user] = useState({ name: 'John Doe', bio: 'Software Engineer' });
const [lang, setLang] = useState('en'); // 'en' or 'ar'
const dir = lang === 'ar' ? 'rtl' : 'ltr';
return (
<div>
<button onClick={() => setLang('en')}>English</button>
<button onClick={() => setLang('ar')}>العربية</button>
<UserProfile user={user} dir={dir} />
</div>
);
};
export default App;
Step 3: CSS Considerations
In addition to the layout considerations in the component, you should also define CSS classes that can handle other UI components like buttons, forms, and text inputs, ensuring they follow the appropriate direction for both languages. For example:
input, button {
direction: inherit;
}
.rtl {
text-align: right;
}
.ltr {
text-align: left;
}
Handling Multi-Language Content
Next, we need to manage multi-language content throughout the application. A solid approach is to use the i18next library, which supports multiple languages and RTL/LTR direction.
Install i18next
Start by installing the necessary packages:
npm install i18next react-i18next
Configure i18next
Here's a basic setup for i18next:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
i18n
.use(initReactI18next)
.init({
resources: {
en: { translation: { welcome: 'Welcome', bio: 'This is my bio' } },
ar: { translation: { welcome: 'أهلا وسهلا', bio: 'هذه سيرتي الذاتية' } },
},
lng: 'en',
fallbackLng: 'en',
interpolation: { escapeValue: false },
});
export default i18n;
Using Translations in Components
Update your UserProfile component to utilize translations:
import React from 'react';
import { useTranslation } from 'react-i18next';
const UserProfile = ({ user, dir }) => {
const { t } = useTranslation();
return (
<div dir={dir} style={{ textAlign: dir === 'rtl' ? 'right' : 'left' }}>
<h1>{user.name}</h1>
<p>{t('bio')}</p>
</div>
);
};
export default UserProfile;
Testing Your Application
It’s vital to test your application for both languages, ensuring that layout, translations, and user interactions function correctly in each context. Tools like Jest and React Testing Library can be used effectively to validate component behavior across different languages.
Here's a simple test case that verifies our translations:
import { render } from '@testing-library/react';
import UserProfile from './UserProfile';
test('renders UserProfile with Arabic text', () => {
const { getByText } = render(<UserProfile user={{ name: 'اسم' }} dir='rtl' />);
expect(getByText('اسم')).toBeInTheDocument();
});
Bottom line
Building bilingual applications in Sharjah requires careful consideration of layout and content direction. By implementing text-align conditionally based on language direction and leveraging libraries like i18next, we can create a seamless experience for both Arabic and English speakers. Effective bilingual support will enhance user engagement and satisfaction in the diverse UAE market, ultimately driving business success.
Building something similar in the UAE market? We'd be happy to talk through the architecture — pixelhorizon.dev/contact.