Helps you write code that works the same for both LTR and RTL languages.
Important
Until 1.0.0
is released, this plugin is in Beta.
Why RTL matters? (Click to expand)
With a global audience of over 800 million people who speak right-to-left (RTL) languages, ensuring RTL readability is essential for international web apps. The eslint-plugin-rtl-friendly is a linter that helps you write RTL-friendly code.
You read this text from left to right.
However, texts in RTL languages are read from right to left.
هذا النص يُقرأ من اليمين إلى اليسار.
Notice how GitHub's markdown aligns the text to the right. This isn’t a bug—it's how RTL languages are read.
Imagine you're writing code the traditional way, creating a button with text and an icon:
return (
<button>
<CheckIcon className="mr-2" />
<span>{getTranslation("buttons.done")}</span>
</button>
);
The code above will work fine for LTR languages, but for RTL languages, the icon will appear on the right side of the text, just like the margin (mr-2
). This means there will be no space between the icon and the text, and there will be extra space at the start of the button.
LTR: [{icon} {text}]
RTL: [{text}{icon} ]
The solution is to use me-2
instead of mr-2
. me-2
stands for margin-inline-end
, which means "right" in LTR languages and "left" in RTL languages. The updated code should be:
return (
<button>
<CheckIcon className="me-2" />
<span>{getTranslation("buttons.done")}</span>
</button>
);
- (ar) Arabic - العربية
- (arc) Aramaic - ܐܪܡܝܐ
- (ckb) Sorani Kurdish - کوردی
- (dv) Divehi - ދިވެހިބަސް
- (fa) Persian - فارسی
- (ha) Hausa - هَوُسَ
- (he) Hebrew - עברית
- (khw) Khowar - کھوار
- (ks) Kashmiri - कॉशुर
- (ps) Pashto - پښتو
- (sd) Sindhi - سنڌي
- (ur) Urdu - اردو
- (uz-Af) Uzbeki Afghanistan - ازبیک
- (yi) Yiddish - ייִדיש
The orange areas on the map below show where RTL languages are spoken.
Currently, the plugin has one rule for Tailwind classes (Feel free to contribute!). It reports and auto-fixes the usage of physical properties classes to their logical counterparts.
The plugin comes with --fix
support out of the box. Run eslint . --fix
and it will automatically fix the issues regardless of how your classes are written. as simple as className="pl-1 mr-2"
or className={clsx(some && "ps-1", {"me-2": isOpen})}
or even referencing a variable className={variable}
(It will report where variable is declared). Have a look at this test file to see what it can fix and what it won't. If you find a case that it doesn't handle, please open an issue.
$ pnpm add -D eslint-plugin-rtl-friendly]
- ESLint >= V9 (Flat Config)
- Tailwindcss V3.3.0 or higher
import rtlFriendly from "eslint-plugin-rtl-friendly";
export default [
// ...
rtlFriendly.configs.recommended,
// More aggressive?
{
rules: {
"rtl-friendly/no-physical-properties": "error",
},
},
];
Rule ID | --fix support |
---|---|
rtl-friendly/no-physical-properties | ✅ |
Welcome your contribution!
- Tailwindcss physical properties to logical properties
- Add support for advanced className like
cn('pl-2', {...})
- Add support for Template Literals tw
... ${...}
- New rule:
dir-attribute
to enforcedir
in<html>
and<code>
tags -
letter-spacing
doesn't work well with RTL languages to disable it in rtl languages, we should warn to disable it in rtlrtl:***
(NOT SURE) - some other cases likeabsolute start-0 -translate-x-1/2
-space-x-*
- Resources