Skip to content

Custom Bundle Generator Module

Use this module to support custom formats of Target File Bundles. The generation process is delegated to your Crowdin app that implements a custom bundle generator module. When translations are ready, Crowdin sends the translation data to your app, which returns the generated bundle in the desired format.

Access

You can grant access to this module to one of the following user categories:

For Crowdin:

  • Only me (i.e., project owner)
  • All project members
  • Selected users

For Crowdin Enterprise:

  • Only organization admins
  • All users in the organization projects
  • Selected users

Structure

manifest.json
{
"modules": {
"custom-file-format": [
{
"key": "your-module-key-type-xyz",
"type": "type-xyz",
"url": "/process",
"multilingualExport": true,
"stringsExport": true,
"extensions": [
".resx"
]
}
]
}
}

Properties

key

Type: string

Required: yes

Description: Module identifier within the Crowdin app.

type

Type: string

Required: yes

Description: Identifier of the custom bundle type. Can be used in the API to trigger the processing of this module when generating translation bundles.

url

Type: string

Required: yes

Description: The relative URL triggered during translation export. Crowdin sends a request to this URL to initiate custom bundle generation.

multilingualExport

Type: bool

Required: no

Allowed values: true, false. Default is false

Description: Enables export of strings for multiple target languages in a single request. Useful for file formats that support multiple languages within the same bundle.

stringsExport

Type: bool

Required: yes

Description: Must be set to true for bundle generator modules. Indicates that the app expects exported strings from Crowdin to generate a custom bundle.

extensions

Type: array

Required: yes

Description: List of file extensions associated with the generated bundles (e.g., .resx, .json). Defines the expected output format and is used for file naming and export handling in Crowdin.

Communication between Custom Bundle Generator App and Crowdin

When a user requests a translation bundle export, Crowdin sends an HTTP request to the app’s configured URL ($baseUrl . $url) with the necessary project, language, and translation data. The app processes the data and responds with the generated bundle file.

The requests and responses to and from the custom bundle generator apps have two-minute timeouts. The maximum request and response payload size is limited to 5 MB.

Request to the App

Request payload example:

// max request payload - 5 MB
// wait timeout - 2 minutes
{
"jobType": "build-file",
"organization": {
"id": 1,
"domain": "{domain}",
"baseUrl": "https://{domain}.crowdin.com",
"apiBaseUrl": "https://{domain}.api.crowdin.com"
},
"project": {
"id": 1,
"identifier": "your-project-identifier",
"name": "Your Project Name"
},
"sourceLanguage": {
"id": "es",
"name": "Spanish",
"editorCode": "es",
"twoLettersCode": "es",
"threeLettersCode": "spa",
"locale": "es-ES",
"androidCode": "es-rES",
"osxCode": "es.lproj",
"osxLocale": "es",
"pluralCategoryNames": ["one"],
"pluralRules": "(n != 1)"
},
"targetLanguages": [
{
// same structure as for sourceLanguage
}
],
"strings": [...], // array of segments
"stringsUrl": "https://tmp.downloads.crowdin.com/strings.ndjson" // file with segments, in new-line delimited json format
}

Properties:

jobType

Type: string

Possible values: build-file

Description: Specifies the action that should be executed by the app. Always set to build-file for bundle generator modules. Crowdin sends translation data and expects a generated bundle in return.

strings, stringsUrl

Type(strings): array

Type(stringsUrl): string

Description: Contains the translation strings for the bundle generation. Either strings (inline array) or stringsUrl (public link to NDJSON) can be used.


Expected Response from the App

Response payload example:

// max response payload - 5 MB
// wait timeout - 2 minutes
{
"data": {
"content": "TWF5IHRoZSBGb3JjZSBiZSB3aXRoIHlvdS4=", // base64 encoded translation file content
"contentUrl": "https://app.example.com/p5uLEpq8p-result.xml", // translation file public URL
},
"error": {
"message": "Your error message"
}
}

Properties:

data.content, data.contentUrl

Type(data.content): string

Type(data.contentUrl): string

Description: Use either data.content (base64 encoded) or data.contentUrl (publicly accessible URL) to return the generated bundle file. Only one of them should be present in the response.

The format of the file depends on your implementation.

error.message

Type: string

Description: An error message that can be passed from the app to Crowdin and will be visible to a user in the UI.

Translation Strings Structure

Below is an example of the structure used to pass translation strings to the app for custom bundle generation.

Payload example:

// strings should be in "new-line delimited json" format if they passed by URL
[
{ // non plural string
"id": 1, // numeric identifier of the string in Crowdin
"identifier": "string-key-1", // required: unique string key
"context": "Some context", // optional: additional info for translators
"customData": "max 4 KB of custom data", // optional: preserved on export
"maxLength": 10, // optional, default null
"isHidden": false, // optional, default null
"hasPlurals": false, // optional, default false
"labels": ["label-one", "label-two"], // optional, default []
"text": "String source text", // required: source content
"translations": { // required: grouped by target language ID
"uk": { // targetLanguage.id
"text": "Переклад стрічки", // required: translation text
"status": "untranslated | translated | approved" // optional, default "translated"
},
// can be other languages for multilingual, check "targetLanguages" in the request payload
}
},
{ // plural string
"id": 2,
"identifier": "string-key-2",
"context": "Some optional context",
"customData": "max 4 KB of custom data",
"maxLength": 15,
"isHidden": false,
"hasPlurals": true,
"labels": [],
"text": { // keys from sourceLanguage.pluralCategoryNames
"one": "One file",
"other": "%d files",
},
"translations": {
"uk": {
"text": { // keys from targetLanguage.pluralCategoryNames
"one": "One file",
"few": "%d файла",
"many": "%d файлів",
},
"status": {
"one": "untranslated",
"few": "translated",
"many": "approved",
}
}
}
}
]

Properties:

id

Type: integer

Required: yes

Description: Numeric identifier of the string in your Crowdin project. Required for mapping translations.

identifier

Type: string

Required: yes

Description: Unique string key within the file. Required.

text

Type: string (non-plural) or object (plural)

Description: Source string text. Required for generating translations. For plural strings, this is an object with plural form keys from sourceLanguage.pluralCategoryNames.

customData

Type: string

Required: no

Description: Any custom data that needs to be linked to the string. Added custom data will be exported along the corresponding strings on translation export.

translations

Type: object

Required: yes

Description: Required translations for each target language. Each language ID maps to an object with a text field, and optionally status. For plural strings, text and status are also objects keyed by plural category names.

Was this page helpful?