Languages
Shared and custom languages, how they attach to namespaces, and what happens when you remove or delete one.
Languages in LangSync exist independently of namespaces: a language does nothing on its own until you attach it to a namespace, at which point every term in that namespace gains a translation slot for it.
There are two kinds:
- Shared languages are global and maintained by Norcube — every
organization can use them. They cover the standard locales (
en,de,cs,pt-BR, …) and cannot be edited or deleted. - Custom languages are scoped to your organization. Use them for dialects, internal variants, or pseudo-locales that the shared list doesn't cover.
Custom languages
A custom language has:
| Field | Rules |
|---|---|
| Code | Must start with a letter; lowercase letters, digits, hyphens, underscores; 1–32 characters (^[a-z][a-z0-9_-]{0,31}$). Unique within your organization. Immutable once created. |
| Name | Human-readable display name, 1–128 characters. |
Custom codes don't have to follow BCP 47, but staying close to it
(en-pirate, en-us-formal) helps when integrating with i18n
libraries that parse locale codes.
A custom language's code may collide with a shared code. When both
exist, anything that looks a language up by code (the API's
languageCode parameters, the CLI) resolves to your custom language
first, then falls back to the shared one. This lets you shadow a
shared language with your own variant without touching your configs.
When to use one
- Brand-voice variants.
en-us-formalanden-us-casualif your product ships two registers. - Pseudo-locales for QA. A custom
qa-zzfilled with obviously wrong values makes missing-translation bugs jump out in screenshots. - Staged rollouts. Use a custom code during beta, switch to the shared code at launch.
For everything else, prefer shared languages — they're zero-config and recognised by translation tooling.
Create and delete
Custom languages are managed via the CLI or the API:
nrc langsync lang create internal-en "Internal English"
nrc langsync lang delete <id>Deleting a custom language is refused with a conflict error while the
language is still attached to any namespace — detach it everywhere
first. Shared languages can never be deleted, only detached from your
namespaces. Both creation and deletion are recorded in the
audit log (custom_language.created /
custom_language.deleted).
Attaching languages to a namespace
A namespace has exactly one default language (the source of truth) and any number of attached target languages.
- Dashboard: open the namespace → ⋯ → Namespace settings → add or remove languages in the languages section.
- CLI:
nrc langsync lang add de --namespace web/nrc langsync lang remove de --namespace web. Runnrc langsync lang list --namespace webto see what's attached, or without--namespaceto list every language available to your organization (theKINDcolumn distinguishessharedfromcustom).
When you attach a language, each term gets an empty slot for it — nothing is translated until you fill it manually or run auto-translate.
The CLI sync can also attach languages
for you: when it finds a local translation file (say pl.json) whose
language isn't attached yet, it attaches the matching language
automatically, asking only when the mapping is ambiguous.
What removal and deletion destroy
This is the part worth reading twice:
| Action | What's deleted | What survives |
|---|---|---|
| Detach a language from a namespace | Every translation in that language, in that namespace. | The terms, all other languages' translations, the language itself (still usable elsewhere). |
| Delete a custom language | The language definition. Refused while attached to any namespace. | Everything else — you must detach first, which is where translations get deleted. |
| Delete a namespace | All translations in all languages of that namespace. | The languages themselves. |
None of these have an undo. If you're unsure, export current state
first — nrc langsync pull writes every language's translations to
local JSON files.
Language IDs vs. codes
Internally every language has a numeric ID, and several API
endpoints (notably the Public API's langId query parameter) speak IDs
rather than codes. IDs are stable — cache them or store them in your
app config. To discover them:
nrc langsync lang listshows theIDcolumn, or- call the Public API's
list-languages endpoint, which returns
id,code, andnamefor each language attached to a namespace.
Dashboard-facing endpoints generally accept either an ID or a code; where both are accepted, the code variant is the more readable choice.
Related
- Namespaces — where languages get attached.
- Auto-translate — filling a newly attached language.
- Public API — fetching translations per language ID.