Nexus AI

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

CodeLanguageDirection
enEnglish (default)LTR
esEspañolLTR
frFrançaisLTR
deDeutschLTR
arالعربية (Arabic)RTL

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 in NextIntlClientProvider.
  • 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

  1. Add the key to every file in messages/ (en.json first, then the others). Keep the same nesting/namespace in each.
  2. Reference it with useTranslations("<namespace>") and t("<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

  1. Add an entry to locales in src/i18n/config.ts:

    { code: "pt", label: "Portuguese", native: "Português", flag: "🇵🇹", dir: "ltr" }
    
  2. Create messages/pt.json (copy en.json and 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.