By taba2177
Strapi ships translations for RTL languages such as Arabic, Hebrew and Persian, also admin panel
released November 9, 2026
npm install strapi-plugin-rtlRight-to-left (RTL) support for the Strapi 5 admin panel.
Strapi ships translations for RTL languages such as Arabic, Hebrew and Persian, but the admin panel stays left-to-right: the layout is not mirrored, menus are indented from the wrong side, and Arabic or Hebrew content is typed into left-aligned fields. This plugin fixes that with no changes to your project code.
dir="rtl".padding-left, margin-right, left: 0…) that dir="rtl" does not flip. The plugin swaps left and right inside Strapi's own style rules at runtime, so menu indents, cards, inputs and icons sit on the correct side. Switching back to an LTR language restores the original styles.ar with the Internationalization plugin), text fields, text areas, the Markdown editor and the Blocks editor become RTL, even if the interface language is English.unicode-bidi: plaintext), so an English brand name inside an Arabic paragraph is not scrambled.Supported RTL languages by default: Arabic (ar), Aramaic (arc), Central Kurdish (ckb), Dhivehi (dv), Persian (fa), Hausa (ha), Hebrew (he), Khowar (khw), Kashmiri (ks), Kurdish (ku), Pashto (ps), Sindhi (sd), Uyghur (ug), Urdu (ur) and Yiddish (yi). Regional codes such as ar-SA or fa-IR are matched by their base language.
@strapi/strapi ^5.0.0)npm install strapi-plugin-rtl
# or
yarn add strapi-plugin-rtlRebuild the admin panel and restart Strapi:
npm run build
npm run developThe plugin is enabled automatically. To let your editors use an RTL interface, add the language to the admin panel in src/admin/app.js (or app.tsx):
export default {
config: {
locales: ['ar'], // 'he', 'fa', …
},
};Each admin then picks the language in Profile → Interface language.
Everything is optional. Add a rtl entry to config/plugins.js (or config/plugins.ts) only to change the defaults:
module.exports = ({ env }) => ({
rtl: {
enabled: true,
config: {
// Mirror the admin panel when the interface language is RTL.
interface: true,
// Make text fields RTL when editing an RTL content locale.
content: true,
// Swap Strapi's left/right styles in an RTL interface.
mirrorStyles: true,
// Languages treated as RTL. Replaces the default list.
rtlLocales: ['ar', 'he', 'fa', 'ur'],
// Extra field names that always stay left-to-right
// (matched as part of the field name, case-insensitive).
ltrFields: ['sku', 'isbn'],
// Extra texts of "back" links whose arrow should point the other way.
backLabels: [],
// Font stack for the RTL interface (load the font yourself).
fontFamily: "'Noto Sans Arabic', sans-serif",
},
},
});| Option | Type | Default | Description |
|---|---|---|---|
interface | boolean | true | Mirror the admin panel when the interface language is RTL. |
content | boolean | true | RTL text fields when the edited locale is RTL. |
mirrorStyles | boolean | true | Swap Strapi's physical left/right styles in an RTL interface. |
rtlLocales | string[] | 15 RTL languages | Language codes treated as RTL. |
ltrFields | string[] | [] | Extra field-name fragments that stay LTR. |
backLabels | string[] | [] | Extra "back" link texts whose arrow is mirrored. |
fontFamily | string | null | null | Font stack for the RTL interface. |
Fields that always stay LTR: input types email, url, number, password, tel, and names containing slug, url, link, href, anchor, email, phone, whatsapp, code, domain, regex, json, canonical, robots, viewport.
Invalid options stop Strapi at startup with a clear message, for example [rtl] "rtlLocales" must be an array of non-empty strings.
Plugin and custom-field authors can opt an element (and everything inside it) out of RTL with the data-rtl-ignore attribute:
<div data-rtl-ignore>
{/* stays left-to-right in an RTL interface */}
</div><pre> and <code> elements, code editors and technical inputs are left-to-right automatically.
The plugin runs only in the admin panel and does not change your API or your content.
<html lang>, set by Strapi) and the content locale in the URL (?plugins[i18n][locale]=…).<html dir="rtl">, adds a small stylesheet, and mirrors Strapi's own style rules: for each rule it swaps padding-left ↔ padding-right, margin-*, left ↔ right, border sides, corner radii and text-align / float values. The swap happens inside the original rule, so CSS specificity and order are unchanged. Rules added later (new screens) are mirrored as they appear.The admin panel reads the configuration from GET /rtl/settings. The endpoint is public because it returns only display options (switches, language codes, field names and a font, never secrets) and the login page needs it before sign-in. Until it loads, the defaults apply, so the panel never flashes left-to-right.
direction: ltr or inline left/right styles are not changed.backLabels if it is not built in.git clone https://github.com/taba2177/strapi-plugin-rtl.git
cd strapi-plugin-rtl
npm install
npm test # unit tests
npm run build # build dist/
npm run verify # check the package before publishingTo try it in a Strapi project, follow Strapi's plugin development guide:
# in the plugin
npm run watch:link
# in your Strapi project
npx yalc add --link strapi-plugin-rtl && npm install
npm run developIssues and pull requests are welcome. Screenshots help a lot for layout problems: please include the interface language and the page.
Share your work with the community and get it listed in the Strapi ecosystem for everyone to discover and use.
Submit
