Internationalization (i18n)
Nexus AI Admin ships with multi-language support powered by
next-intl, using a cookie-based locale — there are
no /en, /es URL prefixes, so your routes stay clean.
A language switcher (the globe icon) sits in the navbar and the docs header.
Included languages
Selecting Arabic flips the entire layout to right-to-left automatically.
The non-English catalogs are a solid starting point — have a native speaker review them (Arabic especially) before going to production.
How it works
src/i18n/config.ts— the locale list, RTL flags, and the cookie name (NEXT_LOCALE).src/i18n/request.ts— reads the locale cookie per request and loads the matching message file.src/i18n/actions.ts— a server action (setLocale) that writes the cookie when the user switches.messages/<locale>.json— the translation catalogs (one per language).src/app/layout.tsx— sets<html lang dir>and wraps the app inNextIntlClientProvider.src/components/layout/language-switcher.tsx— the navbar dropdown.
Using translations in a component
Import useTranslations and reference a namespace + key. It works in both
server and client components.
import { useTranslations } from "next-intl";
export function Example() {
const t = useTranslations("dashboard");
return <h1>{t("title")}</h1>; // "Dashboard" / "Panel" / "لوحة التحكم" …
}
Values with placeholders:
// messages/en.json → "recentActivitySub": "The last {count} events…"
t("recentActivitySub", { count: 10 });
Adding a new string
- Add the key to every file in
messages/(en.jsonfirst, then the others). Keep the same nesting/namespace in each. - Reference it with
useTranslations("<namespace>")andt("<key>").
Keeping the keys identical across files is important — a missing key falls back to the key name (and is flagged in development).
Adding a new language
-
Add an entry to
localesinsrc/i18n/config.ts:{ code: "pt", label: "Portuguese", native: "Português", flag: "🇵🇹", dir: "ltr" } -
Create
messages/pt.json(copyen.jsonand translate the values).
That's it — the switcher, cookie handling and <html lang dir> pick it up
automatically.
Right-to-left (RTL)
RTL is driven by dir="rtl" on <html> (set from the locale's dir flag).
The UI uses logical CSS so it mirrors without per-component work:
- spacing/position:
ms-*/me-*,ps-*/pe-*,start-*/end-* - alignment:
text-start/text-end - direction-specific tweaks:
ltr:/rtl:variants (e.g. the sidebar collapse toggle flips edge and its chevron flips with[&_svg]:rtl:rotate-180)
When you build new UI, prefer these logical utilities over left/right so it
stays RTL-correct.
What's translated
Out of the box: the app shell (sidebar, top bar, user menu, command palette),
the dashboard, sign-in, and settings tabs. The remaining pages render in English
until you add their strings — the framework is fully wired, so it's just a
matter of extracting strings into the messages/ files and swapping in
useTranslations.
Back to the documentation index.