Languages
How the site runs in English and Arabic, how the language is chosen, and what to change to add a language.
The languages that ship
| Language | Address | Direction | Font |
|---|---|---|---|
| English, the default | /en | Left to right | Inter |
| Arabic | /ar | Right to left | Noto Sans Arabic |
Every visible text comes from messages/en.json or messages/ar.json, including the alt texts, the button labels for screen readers and the page's title and description.
How the language is chosen
- The language is the first part of the address:
/enor/ar. - An address without one, such as
/, redirects to the visitor's language: Arabic for a browser set to Arabic, English for every other. For the rest of the browser session it remembers the last language opened, in aNEXT_LOCALEcookie. /enand/aralways open their own language.- The language switch in the navbar and the mobile menu shows the other language's name and keeps the visitor on the page.
- The page's
langanddirfollow the language, and so do the canonical and language links for search engines.
Change a text
Change the value in both message files and keep the key. A key missing from one file shows as a missing-message error on that language's page, so keep the two files in step.
Right to left
The layout uses logical Tailwind classes such as ms-*, pe-*, start-* and end-*, so margins, padding and positions flip by themselves in Arabic. Use them, not ml-* or left-*, when you add markup. Arrow icons turn around with rtl:-scale-x-100.
The site's own Arabic labels
When you write about the site in Arabic, use the labels its page shows:
| English | Arabic | Where |
|---|---|---|
Features | المميزات | Navbar |
Work | الأعمال | Navbar |
Process | المنهجية | Navbar |
Pricing | الأسعار | Navbar |
Contact | تواصل معنا | Navbar button |
Monthly | شهري | Pricing |
Annual | سنوي | Pricing |
Send Message | إرسال الرسالة | Contact form |
Add a language
French as the example, with the code fr:
Add it to the routing
In
src/i18n/routing.ts, add the code tolocales:src/i18n/routing.tslocales: ["en", "ar", "fr"],Create its message file
Copy the English file and translate its values. Keep every key.
Terminalinlanding-page-template-1cp messages/en.json messages/fr.jsonName it in the language switch
Add
"fr": "Français"underlocaleSwitcher.namesin every message file.Give it a social card locale
In
src/i18n/openGraphLocales.ts, addfr: "fr_FR". The build's type check fails until every language has an entry there.For a right-to-left language only
Add its code to
RTL_LOCALESinsrc/i18n/getDirection.ts. The layout loads Noto Sans Arabic foraronly: for another script, load a font for it insrc/app/[locale]/layout.tsx.
The switch toggles between two languages
It shows the first language that is not the current one. With three or more, replace it with a menu in src/components/LocaleSwitcher/.