<header class="flex items-center">

<NuxtImg src="logo.png" class="w-18" alt="Dywan Dev - Digital tools & templates" format="webp" quality="80" loading="lazy" />

<Item><nuxt-link href="/">Home</nuxt-link></Item>

<Item><nuxt-link href="/about">About</nuxt-link></Item>

<Item><nuxt-link href="/works"> Portfolio</nuxt-link></Item>

<Item><nuxt-link href="/contact_me"> Contact</nuxt-link></Item>

<a href="/contact-me" title="Get in touch with Dywan Dev"> Contact </a>

<themeswitch class="moon">Dark/Light</themeswitch>

<langswitch class="en">en/fa</langswitch>

</header>

<initilizecontent class="content">Hello World - Dywan Dev</initilizecontent>

<myname is="Dywan Dev" />

<jobtitle is="Digital tools · Templates · Case studies" />

<portfolios are="ready" number="8" />

<experience years="more than 6" />

<birthdate year="1998" month="july" day="11" />

<skills :list="['NUXT', 'Vue', 'React', 'Next', 'Javascript','Responsive Design', 'i18n', 'TypeScript]" />

<contactDetails :list="['contact@dywandev.com', 'linkedin.com/in/dywan-dev', 'github.com/dywan-dev']" />

Dywan Dev
Blog
Support RTL et LTR dans React avec i18next : guide pratique pour les applications bilingues
5min

Support RTL et LTR dans React avec i18next : guide pratique pour les applications bilingues

Introduction

Créer un site qui fonctionne en arabe comme en anglais semble simple, jusqu’à ce qu’on le fasse vraiment. Changer de langue est facile. En revanche, faire pivoter toute la direction de mise en page — tout en gardant des animations fluides, des images correctement orientées et des composants d’interface naturels — c’est là que beaucoup de développeurs butent.

Ce guide décrit précisément comment j’ai mis en œuvre le support RTL/LTR dans Dywan Dev, une plateforme web full stack construite avec React, Vite et i18next. Pas de théorie : uniquement ce qui fonctionne.

1. Configurer i18next dans une application React + Vite

Installez d’abord les paquets nécessaires :

npm install i18next react-i18next i18next-browser-languagedetector

Créez vos fichiers de traduction :

src/
  locales/
    en/translation.json
    fr/translation.json
    ar/translation.json

Initialisez i18next dans un fichier dédié src/i18n.js :

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

import en from './locales/en/translation.json';
import fr from './locales/fr/translation.json';
import ar from './locales/ar/translation.json';

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    resources: { en: { translation: en }, fr: { translation: fr }, ar: { translation: ar } },
    fallbackLng: 'en',
    interpolation: { escapeValue: false }
  });

export default i18n;

Importez-le une seule fois en haut de main.jsx :

import './i18n';

2. Gérer le changement de direction — la bonne approche

C’est là que beaucoup de tutoriels s’arrêtent trop tôt. Changer la langue ne suffit pas : il faut mettre à jour dynamiquement les attributs HTML dir et lang à chaque changement de langue.

Créez un hook personnalisé useDirection.js :

import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';

const RTL_LANGUAGES = ['ar'];

export const useDirection = () => {
  const { i18n } = useTranslation();

  useEffect(() => {
    const isRTL = RTL_LANGUAGES.includes(i18n.language);
    document.documentElement.dir = isRTL ? 'rtl' : 'ltr';
    document.documentElement.lang = i18n.language;
  }, [i18n.language]);
};

Appelez ce hook une fois dans votre App.jsx racine :

import { useDirection } from './hooks/useDirection';

function App() {
  useDirection();
  return (...);
}

Désormais, toute votre mise en page réagit automatiquement aux changements de langue.

3. La partie délicate — animations et images en RTL

C’est ce dont peu d’articles parlent. Lorsque vous passez en RTL, le CSS gère automatiquement le texte et une grande partie de la mise en page. En revanche, les animations et les images ne suivent pas toujours.

Animations

Si vous utilisez Framer Motion, les animations directionnelles doivent respecter le sens de lecture actuel. Au lieu de coder en dur x: 100, déterminez la direction dynamiquement :

import { useTranslation } from 'react-i18next';

const { i18n } = useTranslation();
const isRTL = i18n.language === 'ar';

const slideVariant = {
  hidden: { x: isRTL ? -100 : 100, opacity: 0 },
  visible: { x: 0, opacity: 1 }
};

Images

Les images directionnelles à vocation décorative — flèches, personnages orientés, illustrations d’interface — peuvent nécessiter un effet miroir en RTL. Utilisez une classe CSS appliquée conditionnellement :

.mirror-rtl {
  transform: scaleX(-1);
}
<img
  src={arrow}
  className={isRTL ? 'mirror-rtl' : ''}
  alt="direction indicator"
/>

N’appliquez cela qu’aux images pour lesquelles la direction a un sens visuel. Toutes les images n’ont pas besoin d’être inversées — seulement celles qui suggèrent explicitement une direction.

4. Tailwind CSS et RTL

Tailwind v3 et suivants intègrent la prise en charge du RTL. Configurez-le dans tailwind.config.js (les chemins content par défaut conviennent en général) ; utilisez ensuite les variantes ltr: et rtl: pour les utilitaires directionnels :

<div class="ltr:pl-4 rtl:pr-4">
  Content
</div>

Cela permet de garder une mise en page claire sans écrire de feuilles de style RTL séparées.

5. Composant de changement de langue

Voici un sélecteur minimal et lisible qui met à jour à la fois la langue et la direction :

import { useTranslation } from 'react-i18next';

const languages = [
  { code: 'en', label: 'EN' },
  { code: 'fr', label: 'FR' },
  { code: 'ar', label: 'ع' }
];

export const LanguageSwitcher = () => {
  const { i18n } = useTranslation();

  return (
    <div className="flex gap-2">
      {languages.map(({ code, label }) => (
        <button
          key={code}
          onClick={() => i18n.changeLanguage(code)}
          className={
            i18n.language === code
              ? 'px-3 py-1 rounded bg-primary text-white'
              : 'px-3 py-1 rounded bg-transparent'
          }
        >
          {label}
        </button>
      ))}
    </div>
  );
};

Conclusion

Le support du RTL n’est pas qu’un problème de traduction — il engage aussi la mise en page, l’animation et l’expérience utilisateur. La combinaison d’i18next pour les contenus, d’un hook de direction pour les attributs HTML et d’une logique conditionnelle pour les animations couvre environ 95 % des cas réels.

Si vous ciblez les marchés arabophones — ou tout public bilingue — bien le mettre en place dès le départ vous évite des refactorisations importantes par la suite.

Dywan Dev repose sur cette architecture exacte : une plateforme multilingue prête pour le RTL, pensée pour une portée internationale. Si vous avez besoin d’un site qui parle littéralement la langue de votre audience, contactez-moi.

Continuer la lecture

Voir toutVoir tout
WhatsApp