Turn on right-to-left
Set the page direction and every component, block and template mirrors. Add the direction provider, write RTL-safe code and test it.
On this page
Set the direction
Set dir and lang on <html>, and wrap the app in DirectionProvider so the Radix-based components (tabs, sliders, menus, radio groups) know the direction too.
pnpm dlx shadcn@latest add @ballmac/directionnpx shadcn@latest add @ballmac/directionyarn dlx shadcn@latest add @ballmac/directionbun x shadcn@latest add @ballmac/directionimport { DirectionProvider } from "@/lib/ballmac/direction"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ar" dir="rtl">
<body>
<DirectionProvider dir="rtl">{children}</DirectionProvider>
</body>
</html>
)
}Items that need the direction in code (Tabs, Slider, Calendar, Carousel, Sidebar and others) add it for you. They also read <html dir> on their own, so an app that sets only the attribute still works. The provider adds the Radix side.
Give a region its own direction with <Dir dir="ltr">.
Test it
Every component and block preview has a right-to-left toggle in its toolbar. Any preview opens right-to-left with /preview/<name>?dir=rtl.
pnpm rtl:sweep loads every preview in both directions and reports any whose layout isn't the mirror image of the other, or that overflows only in RTL.
Write RTL-safe code
The repository checks this on every build (pnpm check runs scripts/rtl.ts):
- Physical classes are rejected:
ml-mr-pl-pr-becomems-me-ps-pe-;left-andright-becomestart-andend-;text-leftbecomestext-start;border-lbecomesborder-s;rounded-lbecomesrounded-s. Centering withleft-1/2 -translate-x-1/2is symmetric and allowed. - Directional icons from lucide-react must have an
rtl:class.npx tsx scripts/rtl.ts --fixrewrites the safe cases. - Anything that is physical on purpose carries a comment containing
rtl-fixedand a reason, or is listed inscripts/rtl-exceptions.json. - A
translate-xnudge needs its mirror:group-hover:translate-x-1 rtl:group-hover:-translate-x-1.
Know the limits
- Templates mirror, but their sample copy is English and written into the files, so translate it as you would any content.
- Recharts draws SVG in its own coordinates: axes don't mirror. Pass
reversedto an axis yourself if your design needs it. - The marquee and blur-fade
directionprops are physical. Choose the value you want for your reading direction.