Server

Locales

Learn how to add, override and use translations in the OpenSya Nest runtime.

Locales define translations used by the OpenSya backend runtime.

They allow applications and modules to add new translation keys, override existing translations and support additional languages.

OpenSya automatically discovers locale files from the server/locales directory and merges them with the native runtime translations.

Locales make OpenSya applications customizable, multilingual and module-friendly.

Filesystem Structure

Locale files are placed inside the server/locales directory.

Structure
server/locales/
├── fr/
│   └── common.json
└── en/
    └── common.json

Each language has its own directory.

Each JSON file represents a translation namespace.

Adding Translations

You can add new translations by creating a JSON file inside a language directory.

server/locales/fr/common.json
{
  "candidate": {
    "created": "Candidat créé avec succès",
    "not_found": "Candidat introuvable"
  }
}

The translations are automatically loaded by the runtime.

Merging With Native Translations

OpenSya includes native translation files.

When you create a locale file with the same language and filename as a native locale, OpenSya merges your file with the native one.

Example:

Merge Example
server/locales/fr/common.json
        +
native fr/common.json
merged fr/common.json

This allows you to add or override specific translation keys without replacing the entire native translation file.

Local translations are merged with native OpenSya translations when they share the same language and filename.

Overriding Existing Translations

You can override an existing translation by declaring the same key in your project locale file.

server/locales/fr/common.json
{
  "session": {
    "errors": {
      "not_authorized": "Vous n'êtes pas autorisé à effectuer cette action."
    }
  }
}

If the key already exists in the native fr/common.json, your project value takes precedence.

Be careful when overriding native translation keys.Changing native messages can affect runtime errors, guards, services and built-in behaviors.

Adding a New Language

You can add a new language by creating a new language directory.

New Language
server/locales/
└── wo/
    └── common.json

Example:

server/locales/wo/common.json
{
  "session": {
    "errors": {
      "not_authorized": "Amoo sañ-sañ ci jëf jii."
    }
  }
}

If the language does not exist natively, OpenSya creates and registers it during runtime initialization.

Namespaces

The filename represents the translation namespace.

Namespaces
server/locales/fr/common.json   → common
server/locales/fr/session.json  → session
server/locales/fr/errors.json   → errors

Example:

server/locales/fr/session.json
{
  "errors": {
    "expired": "Votre session a expiré."
  }
}

The namespace helps organize translations by domain.

Using Translations

Translations can be accessed using useTranslate() or $t.

Using useTranslate()

server/services/session/validate.ts
const t = useTranslate();

throw new Error(t('session.errors.not_authorized'));

Using $t

server/guards/roles.ts
export default defineGuard(({ controllerOptions, request }) => {
  if (!controllerOptions.roles) return;

  if (!controllerOptions.roles.includes(request._user?.role)) {
    return {
      pass: false,
      errorMessage: $t('session.errors.not_authorized'),
    };
  }
});

Both helpers resolve translations from the runtime i18n registry.

Common Use Cases

Locales are useful for:

Use CaseDescription
Runtime errorsTranslate errors returned by guards, services or controllers.
Validation messagesProvide localized validation feedback.
Module translationsAllow modules to expose their own translations.
Native overridesCustomize built-in OpenSya messages.

Runtime Discovery

During startup, OpenSya automatically:

  1. Discovers locale directories
  2. Loads JSON translation files
  3. Merges project locales with native locales
  4. Registers new languages
  5. Makes translations available through useTranslate() and $t
Runtime Lifecycle
Filesystem Discovery
Locale Loading
Native Locale Merge
Language Registration
Runtime Translation

Best Practices

Use clear and stable translation keys.

Prefer domain-based namespaces and nested keys.

Recommended
{
  "candidate": {
    "errors": {
      "not_found": "Candidate not found"
    },
    "messages": {
      "created": "Candidate created successfully"
    }
  }
}

Avoid using long sentences as translation keys.

Not Recommended
{
  "Candidate was not found in the database": "Candidate was not found in the database"
}
Keep translations organized by language, namespace and domain.

Philosophy

Locales are part of the OpenSya runtime customization layer.

They allow recruitment and business platforms to adapt messages, errors and module text without modifying native runtime code.

This keeps applications customizable while preserving a clean and modular architecture.