Skip to main content
PrimeDev
Front-end9 min read

Bilingual Next.js: Lessons from Shipping Persian and RTL

Niloofar AhmadiFrontend Engineer

Real Persian support is much more than dir="rtl". This note distills what we've learned across several bilingual projects.

Rule one: no strings in components

Every piece of text — including accessibility labels and error messages — must come from the translation catalog. We use next-intl, and a CI script fails the build when a hardcoded string shows up in JSX.

Rule two: CSS logical properties

Use margin-inline-start instead of margin-left; inset-inline-start instead of left. Layouts then work in both directions with zero conditionals. Directional icons (arrows) are the only exception — they flip with rtl:rotate-180.

Rule three: native numbers and dates

The Persian calendar via Intl.DateTimeFormat('fa-IR-u-ca-persian') and Persian digits via Intl.NumberFormat('fa-IR') are available natively — no extra library needed.

The result? A site that doesn't feel translated to Persian speakers — it feels Persian-first.