[data-reveal]{opacity:1!important;transform:none!important}
Extending
Translation

Extending

Ship translations from your own module, load a workspace in another app, and call the Lang HTTP API.

The Lang module has no AntelopeJS interface of its own. Other code plugs into it through locale files, the public endpoint, the HTTP API and the realtime topic.

Supported extension boundary

The contracts on this page are the supported integration points. The runtime root also re-exports its page and route classes, but those exports are not a separate extension SDK or a supported subclassing contract. Do not register those controllers again or call their implementation methods to bypass the HTTP guards. Define your own pages through @antelopejs/interface-dms; use the documented locale, HTTP and realtime contracts to integrate with Lang.

Ship translations from a module

Any DMS frontend module registered with AddFrontendModule contributes its <name>-<xx-XX>.json files from the discovered locale directories. Lang discovers them through GetFrontendModules() and checks their file stamps on reads, so a file change shows on the next read.

frontend-vue/
  i18n/
    locales/
      my_module-en-GB.json
      my_module-fr-FR.json
  • A module's files appear in the Installed modules workspace, read-only. A project redefines a text by overriding the key into its project files.
  • Your project's own frontend module carries options: { dmsI18nAppLayer: true }: its <name>-<xx-XX>.json files become the writable Project files, split in as many files per language as you like (see Project files).
A frontend module registered or removed after Lang started, in its own construct or start, shows up or leaves within a couple of seconds, without a restart. Changes to existing files show on the next read.

Re-registering a module with a different dmsI18nAppLayer option also updates its origin on the next module refresh, even if its files have not changed. The messages, matrix rows and coverage then reflect the new origin.

Load a workspace in another app

Every workspace you create is served publicly, without credentials, to any origin:

Terminal
curl https://api.example.com/i18n/storefront/fr.json

The file is the nested message tree of the language. It leaves out the keys the language has no text for, so load the base language too and let your i18n library fall back. The Use in your app card of the workspace settings generates the vue-i18n and i18next setup for you.

For example, after translating checkout.pay to Payer maintenant in fr, the response includes:

Example response
{
  "checkout": {
    "pay": "Payer maintenant"
  }
}

Your app looks up checkout.pay in this tree. If checkout.cancel exists only in the base language, it is absent from this response; the endpoint does not merge the base text into French for you. Configure fallback in your i18n library.

Check HTTP status before reading the response as messages. A missing workspace or locale returns 404, which is different from a valid locale with missing keys. The public endpoint needs no token: keep private data out of these files.

HTTP API

The dashboard pages read and write through /api/lang/translations. Every route is reserved to the platform owner (@AuthOwnerOnly), and every write also checks the permission of its page action, and requires editable: true.

Workspaces are platform-wide catalogs, not tenant-isolated resources. These routes select a workspace by id, not by tenantId; the public /i18n route has no tenant or authentication guard. Use these endpoints for public translations, not private tenant data. Changing workspacesDir changes the process-wide storage root, not its access policy.

Method and pathPurposePermission (action)
GET /workspaces, GET /summaryEvery workspace with its locales, keys and coverageOwner
GET /flat?workspace=The flattened keys and values of a workspaceOwner
GET /export, GET /backupOne language as JSON, or the whole workspace as a backupOwner
POST /workspace, POST /importCreate a workspace, or create one from a backupWorkspaces › create
PATCH /workspaceUpdate the description and typeWorkspace general › edit
POST /workspace/rename, DELETE /workspaceRename or delete a workspaceDanger zone › rename, delete
POST /locale, DELETE /languages/:workspace/:code, POST /languages/:workspace/:code/baseAdd, remove, or make base a languageWorkspace general › languages
POST /key, POST /key/rename, DELETE /keyCreate, rename or delete a keyMatrix › keys
PUT /key, DELETE /key/override, POST /key/reviewedWrite values, drop an override, mark a key reviewedMatrix › edit

Permission ids follow the page tree, for example modules.lang.translate.translations.scoped.matrix.edit, modules.lang.translate.translations.scoped.matrix.keys and modules.lang.manage.workspaces.list.create.

Realtime

Every write publishes on the dms-lang.translations topic. The Lang pages subscribe to it, so another tab, or another user, sees a change without reloading. Subscribe a page of your own with RegisterPageTopic to react to translation changes.

The pages react to query parameters, which you can use in links and quick actions:

QueryPagesEffect
workspace=<id>AllSelects the workspace (default, modules or one you created)
locale=<code>Translation queueSelects the language
filter=missingTranslation matrixShows the incomplete keys
action=add-key, add-language, new-workspaceMatrix, Overview, WorkspacesOpens the matching dialog on arrival