Manifest
manifest.json describes the app. Point $schema at the bundled JSON Schema to get validation and autocomplete in your editor:
{ "$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" }] }}Top-level fields
Section titled “Top-level fields”| Field | Required | Description |
|---|---|---|
name | yes | Human-readable app name (2-255 characters) shown in Crowdin |
bundle | yes | Where Crowdin loads the bundle from - see bundle |
scopes | yes | What the in-app API client may do on the user’s behalf - see scopes |
modules | yes | The UI modules the app adds to Crowdin, keyed by module type - see modules |
description | no | App description |
logo | no | Logo path served from the bundle root; a root-relative path beginning with /, e.g. /logo.svg for public/logo.svg |
stringBasedAvailable | no | Whether the app is offered in string-based projects in addition to file-based ones (default false) |
default_permissions | no | Default audience after installation - see default_permissions |
bundle
Section titled “bundle”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.
scopes
Section titled “scopes”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.
default_permissions
Section titled “default_permissions”Who the app is available to right after installation (the admin can change it later - see app installation):
| Key | Values | Default |
|---|---|---|
user | owner, managers, all, guests | owner |
project | own, restricted | own |
Modules
Section titled “Modules”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:
| Field | Required | Description |
|---|---|---|
key | yes | Unique within the app (3-255 characters; letters, digits, _, -); disambiguates multiple modules of the same type |
name | yes | Human-readable module name (3-255 characters) |
logo | no | Logo path served from the bundle root, e.g. /logo.svg |
Some module types require extra fields:
| Module type | Extra required fields |
|---|---|
editor-right-panel, editor-translations-panel, editor-background-worker | modes |
editor-asset-panel | fileNamePattern |
context-menu | options |
| all other types | none |
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
fileNamePattern
Section titled “fileNamePattern”Asset-panel modules declare which asset files they handle with a wildcard pattern, e.g. "*.psd".
options (context-menu)
Section titled “options (context-menu)”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):
| Field | Required | Description |
|---|---|---|
location | yes | Which Crowdin context menu the entry is added to: tm, glossary, language, screenshot, style_guide, source_file, translated_file |
type | yes | What activating the entry does: modal opens one of the app’s modal modules, redirect jumps to one of the app’s menu modules |
module | yes | The 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 |
Example with several module types
Section titled “Example with several module types”{ "$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" } } } ] }}Syncing with Crowdin
Section titled “Syncing with Crowdin”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.