Skip to the article
Aniq-UI

NorthstackLanguages

Languages

How the website and the dashboard run in English and Arabic, how to change any text, what the API translates, and what to change to add a language.

For the Full Stack package

The languages that ship

English and Arabic, in all three apps. Arabic lays the whole interface out right to left, with its own typefaces, and the product name stays Northstack in Latin letters in both languages. Prices on the website are written the same way in both, the dollar sign first in Latin digits.

AppEnglishArabic
Website/en/…/ar/…
Dashboard/en/…/ar/…
APIAccept-Language: enAccept-Language: ar

English is the default. French, Spanish and other languages are not included; the sections below say what adding one takes.

How the language is chosen

  • The language is the first part of the address. The Language menu swaps it and keeps the page.
  • The website: a path without a language is sent by next-intl to the visitor's earlier choice or their browser's language when it is English or Arabic, and to /en otherwise. The sitemap lists every page in both languages, each with its alternate.
  • The dashboard: a path without a language opens in the language the dashboard last served in that browser (the NEXT_LOCALE cookie), English otherwise, and the bare address opens /<language>/dashboard. Every request it makes sends the page's language to the API as Accept-Language.
  • A password reset link opens the dashboard in the language the reset was asked for, and the licence checkout's return pages open in the language the buyer checked out in.

Change a text

Every visible word lives in messages/<namespace>/en.json and ar.json, in each frontend's folder. Change the value, keep the key, and change it in both files.

AppNamespaces
Websitelayout, home, pricing, checkout, docs, blog, changelog, contact, legal, sampleData. The documentation, journal and changelog texts are in src/content/docs/, src/content/journal/ and src/content/changelog/, one en.json and one ar.json each.
Dashboardai-assistant, auth, common, dashboard (with a folder per area: activity, billing, overview, platform, projects, roles, settings with adminmanagement, adminroles, appsettings, profile and security, team, ui-component, users), invitation, layouts, metadata (the tab titles), onboarding
  • A key missing from ar.json shows as a missing message on the Arabic side, so keep the two files in step.
  • Text inside {curly} braces is filled in by the app, such as {count} or {license}. Keep those words as they are in both languages, and keep the tags inside a message, such as <code> or <card>, around their text.

Text the workspace stores in both languages

  • A project's name and description and a task's title and description are kept per language, as translations: { en, ar }. The English name or title is required; the Arabic one is optional, and the Arabic dashboard shows the English text wherever the Arabic is empty. The seed fills both for every sample project and task.
  • The platform's permissions and settings carry their labels and descriptions in both languages too.
  • The workspace's Language in Settings is the language of its emails for anyone who has chosen no language of their own. The language of the screens is always the one in the address.
  • The AI assistant answers in the language of the page it is asked from, unless the person writes in another one.

What the API translates

  • Error messages come back in the language of the Accept-Language header, and so does the message of a successful sign-in, profile, staff, role or settings change; other answers carry a fixed code (such as checkout_started) that the frontend words itself. ar-SA counts as Arabic; any language the API does not have falls back to English.
  • Its own texts are JSON files in back-end/src/i18n/translations/en/ and ar/, one per area: admin, auth, common, mail, project, roles, settings, tasks, users.
  • Projects and tasks come back with both languages, as { "en": {…}, "ar": {…} }, and the dashboard picks one.
  • The emails about a workspace (invitations, the weekly digest and the billing emails) are written from mail.json in the recipient's language: their own choice, else the workspace's Language, else English (back-end/src/modules/mail/recipient-locale.ts). The password reset email (back-end/src/modules/auth/account.service.ts) and the licence receipt (back-end/src/modules/licenses/services/license-checkout.service.ts) are written in English, with links in the reader's language; translate them there if your customers need Arabic ones.

Add a language to the website

The two languages are written into a few files, so adding a third touches each of them. Paths are inside website/.

  1. Add the code to locales in src/i18n/routing.ts. That list decides which addresses exist, what the sitemap lists and which language a path without one goes to.
  2. Copy every messages/<namespace>/en.json to a file named after the new code and translate the values. src/i18n/request.ts loads one file per namespace for each language, so none may be missing.
  3. Do the same for src/content/docs/, src/content/journal/ and src/content/changelog/, and add the new file to the byLocale table in each folder's index.ts.
  4. If the language is written right to left, extend the dir line in src/app/[locale]/layout.tsx, which only knows ar, and give it a typeface in src/styles/fonts.css.
  5. The checkout sends en or ar to the API (src/features/checkout/hooks/useCheckoutForm.ts), and the API accepts only those two. Search src/ for "ar" and handle the new code there too.

Add a language to the dashboard

  1. Add the code to locales in src/config/i18n.ts and in src/proxy.ts, and, if it is written right to left, to RTL_LOCALES in src/app/layout.tsx and the check in src/hooks/locale/useDirection.ts.
  2. Copy every messages/**/en.json to a file named after the new code, and translate the values.
  3. Search src/ for "ar": dates, charts, the assistant's widgets and a few settings choose between the two languages directly, and pickLocale in src/lib/api/shared.ts picks a stored text in English or Arabic.
  4. The project and task forms ask for English and Arabic. A third language in the stored texts also needs the API to accept it.

Add a language to the API

The API knows en and ar in supportedLocales in back-end/src/i18n/i18n.service.ts. Add the new code there, copy src/i18n/translations/en/ to a folder named after it, and translate the files. Stored texts are an { en, ar } pair, validated by the translations classes in src/modules/projects/dto/project.dto.ts and src/modules/tasks/dto/task.dto.ts, so a third language in the data is a change to those classes, the entities, the AI assistant's tools and the seed. The licence checkout accepts en or ar in src/modules/licenses/dto/start-license-checkout.dto.ts.

Stuck on a step?

Find a fix before you start over.

Troubleshooting

Cookie Preferences

We use cookies to enhance your browsing experience, analyze site traffic, and personalize content. By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising.