Skip to content

Manifest

manifest.json describes the app. Point $schema at the bundled JSON Schema to get validation and autocomplete in your editor:

manifest.json
{
"$schema": "./node_modules/@crowdin/serverless-apps-sdk/manifest.schema.json",
"name": "My App",
"bundle": { "mode": "internal" },
"scopes": ["project:read"],
"modules": {
"project-menu": [{ "key": "menu", "name": "My App" }]
}
}
FieldRequiredDescription
nameyesHuman-readable app name (2-255 characters) shown in Crowdin
bundleyesWhere Crowdin loads the bundle from - see bundle
scopesyesWhat the in-app API client may do on the user’s behalf - see scopes
modulesyesThe UI modules the app adds to Crowdin, keyed by module type - see modules
descriptionnoApp description
logonoLogo path served from the bundle root; a root-relative path beginning with /, e.g. /logo.svg for public/logo.svg
stringBasedAvailablenoWhether the app is offered in string-based projects in addition to file-based ones (default false)
default_permissionsnoDefault audience after installation - see default_permissions

bundle.mode is internal (Crowdin serves the bundle you uploaded with publish) or external (Crowdin loads it from bundle.url - your own hosting or the local dev server). With external, url is required and points at a folder: the host appends app.js to it.

This field is managed for you by the CLI’s dev and publish commands - see how dev and publish work.

OAuth-style scopes the app may exercise against the Crowdin REST API on behalf of the current user; calls outside these scopes are rejected. An empty array means no API access.

See understanding scopes for the list - e.g. project, project.translation, tm, glossary. Narrow a scope with the :read or :write postfix (e.g. project:read); note that :write does not imply read access.

Who the app is available to right after installation (the admin can change it later - see app installation):

KeyValuesDefault
userowner, managers, all, guestsowner
projectown, restrictedown

Every entry under modules is a list, keyed by module type. The schema enumerates the module types the installed SDK version supports - new types arrive with SDK releases. All modules share three core fields:

FieldRequiredDescription
keyyesUnique within the app (3-255 characters; letters, digits, _, -); disambiguates multiple modules of the same type
nameyesHuman-readable module name (3-255 characters)
logonoLogo path served from the bundle root, e.g. /logo.svg

Some module types require extra fields:

Module typeExtra required fields
editor-right-panel, editor-translations-panel, editor-background-workermodes
editor-asset-panelfileNamePattern
context-menuoptions
all other typesnone

Editor modules declare the editor modes and views they appear in - a unique, non-empty subset of:

translate, review, assets, comfortable, side-by-side, multilingual

Asset-panel modules declare which asset files they handle with a wildcard pattern, e.g. "*.psd".

Context-menu entries declare where they appear and what they do (see the context menu module docs for how the entries look in the Crowdin UI):

FieldRequiredDescription
locationyesWhich Crowdin context menu the entry is added to: tm, glossary, language, screenshot, style_guide, source_file, translated_file
typeyesWhat activating the entry does: modal opens one of the app’s modal modules, redirect jumps to one of the app’s menu modules
moduleyesThe target module as a single {"<module type>": "<module key>"} pair, e.g. {"modal": "details"}. modal entries always use the modal type; redirect entries use a menu module type allowed for the location: organization-menu (Crowdin Enterprise) or profile-resources-menu (crowdin.com) for tm, glossary and style_guide; project-tools, project-reports, project-menu or project-integrations for the rest
manifest.json
{
"$schema": "./node_modules/@crowdin/serverless-apps-sdk/manifest.schema.json",
"name": "My App",
"description": "Editor panel and TM context menu",
"logo": "/logo.svg",
"bundle": { "mode": "internal" },
"scopes": ["project:read", "tm:read"],
"modules": {
"editor-right-panel": [
{ "key": "panel", "name": "My Panel", "modes": ["translate", "review"] }
],
"modal": [{ "key": "details", "name": "Details" }],
"context-menu": [
{
"key": "tm-action",
"name": "Open in My App",
"options": { "location": "tm", "type": "modal", "module": { "modal": "details" } }
}
]
}
}

Crowdin stores its own copy of the manifest for the registered app. Use the CLI’s manifest status / pull / push commands to diff and sync it with your local file.

The CLI itself does not validate the manifest against the schema - validation happens server-side when the manifest is pushed, so keep $schema in the file to catch mistakes in your editor as you type.