Crowdin Apps JS
The Crowdin Apps JS is a JavaScript library that enables communication between your app and the Crowdin UI. Since all Crowdin Apps run inside a sandboxed <iframe>, they are isolated and cannot directly access the main Crowdin page’s content or code.
This library solves that problem by providing a secure cross-window messaging (postMessage()) bridge. After including the library, you will have access to a global AP (App Project) object. This object is your single entry point for calling methods (like AP.getContext()) and subscribing to events (like AP.events.on()).
To use the AP object, you must include the iframe.js script in the <head> of your app’s HTML page.
<script src="https://cdn.crowdin.com/apps/dist/iframe.js"></script>Global actions are available in every context where your app can be loaded (e.g., in a modal, the project “Tools” tab, or the Editor sidebar). They are all called directly from the root AP object.
These methods allow your app to get essential information about its environment, such as the current project, user, and active UI theme.
Retrieves a ContextDataObject containing key information about the environment where the app is currently running (e.g., project ID, user, and file data).
Example:
AP.getContext(function(contextData) { if (contextData) { console.log("Current project ID:", contextData.project_id); if(contextData.editor) { console.log("Current file name:", contextData.editor.fileData.name); } }});callback | Type: Required: yes Description: A callback function that handles the response. It receives one argument: the |
{ "project_id": 123, "organization_id": 100001, "editor": { "mode": "translate", "theme": "dark", "source_language_id": "en", "target_language_id": "fr", "file": 987, "fileData": {35 collapsed lines
"id": "987", "is_plain_text": true, "type": "android", "status": "1", "parent_id": "0", "node_type": "1", "created": "2025-01-01 10:30:00", "extension": "xml", "priority": "1", "name": "example_file.xml", "upload_ready": 1, "export_ready": 1, "export_xliff_ready": 1, "can_change": 1, "plural_support": 1, "excluded_languages": [], "html_preview": 0, "identifier_required": 1, "total": 50, "translated": 10, "approved": 5, "preTranslated": 0, "translated_percent": 20, "approved_percent": 10, "progress": { "total": 50, "translated": 10, "approved": 5, "translated_percent": 20, "approved_percent": 10, "pre_translated": 0, "file_id": 987, "language_id": 2, "translation_link": "/editor/project-name/987/en-fr" } }, "workflow_step": { "id": 7777, "title": "Translation", "type": "Translate" } }}project_id | Type: Description: The unique numeric ID of the current project. |
organization_id | Type: Description: The unique numeric ID of the organization (Crowdin Enterprise only). |
editor | Type: Description: An object containing the Editor context. |
editor.mode | Type: Allowed values: Description: The current mode of the Editor. |
editor.theme | Type: Allowed values: Description: The current UI theme of the Editor. |
editor.source_language_id | Type: Description: The ID of the source language (e.g., |
editor.target_language_id | Type: Description: The ID of the current target language (e.g., |
editor.file | Type: Description: The numeric ID of the file currently open in the Editor. |
editor.fileData | Type: Description: A detailed object containing data about the open file. (This object is the same
as one returned in |
editor.fileData.id | Type: Description: The file ID (as a string). |
editor.fileData.name | Type: Description: The name of the file. |
editor.fileData.node_type | Type: Description: The type of node ( |
editor.fileData.total | Type: Description: Total number of strings in the file. |
editor.fileData.progress | Type: Description: An object containing translation progress data for the current language. |
editor.fileData.progress.translation_link | Type: Description: A relative URL path to the file in the Editor. |
editor.workflow_step | Type: Description: Crowdin Enterprise only. Details of the current workflow step.
|
editor.workflow_step.id | Type: Description: The numeric ID of the workflow step. |
editor.workflow_step.title | Type: Description: The display name of the workflow step. |
editor.workflow_step.type | Type: Description: The type of the workflow step (e.g., |
Retrieves the name of the currently active user interface (UI) theme.
Example:
AP.getTheme(function(themeName) { console.log("Current theme:", themeName); // e.g., 'light', 'dark', or 'auto'});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one argument: a |
This method returns a plain string.
"light"Type: string
Allowed values: light, dark, auto
Retrieves an object containing all active Crowdin CSS variables. This allows your app to style its elements to match the user’s UI theme for a seamless look and feel.
Example:
AP.getCssVariables(function(variables) { if (variables) { // Set our app's text color to match Crowdin's document.body.style.color = variables['--crowdin-body-color']; }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one argument: an |
{ "--crowdin-level-1-bg": "#f5f7f8", "--crowdin-level-2-bg": "#ffffff", "--crowdin-body-bg": "#f5f7f8", "--crowdin-title-color": "rgba(38, 50, 56, 1)", "--crowdin-body-color": "rgba(38, 50, 56, 0.87)", "--crowdin-text-muted": "rgba(38, 50, 56, 0.54)", "--crowdin-primary": "rgba(67, 160, 71, 1)", "..." : "..."}Returns an object where each key is a CSS variable name (e.g., "--crowdin-primary") and the value is its current computed value (e.g., "rgba(67, 160, 71, 1)").
Retrieves the current user’s authentication JWT token. This token can be used to make Crowdin API v2 requests on behalf of the user.
Example:
AP.getJwtToken(function(token) { if (token) { console.log("My JWT:", token); } else { console.log("Token is not available in this context."); }});callback | Type: Required: yes Description: A callback function that handles the response. It receives one argument: a |
This method returns a plain string which is the JWT token, or null.
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkw...SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"This group of methods allows your app to get information about the size and position of its iframe and to request size changes.
Retrieves the current visible dimensions of the app’s iframe. This is useful for knowing how much of your app is actually visible to the user as they scroll.
Example:
AP.getViewportSize(function(viewport) { console.log("Visible iframe width:", viewport.width); console.log("Visible iframe height:", viewport.height);});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one
|
{ "width": 800, "height": 250}width | Type: Description: The visible width of the iframe in pixels. |
height | Type: Description: The visible height of the iframe in pixels, adjusted for the main Crowdin header and scrolling. |
Retrieves the dimensions of the entire browser window (the top window), not just the app’s iframe.
Example:
AP.getWindowSize(function(windowSize) { console.log("Browser window width:", windowSize.width); console.log("Browser window height:", windowSize.height);});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one
|
{ "width": 1440, "height": 900}width | Type: Description: The total width of the browser window in pixels. |
height | Type: Description: The total height of the browser window in pixels. |
Retrieves the vertical scroll position of the app’s iframe relative to the top of the main window’s viewport.
This returns 0 if the top of the app is visible. If the user scrolls the page down, the value will be a positive number indicating how many pixels of the app are scrolled out of view.
Example:
AP.getScrollPosition(function(scrollPosition) { console.log("App is scrolled by:", scrollPosition, "pixels"); // Example output: 150});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one
|
This method returns a plain integer representing the number of pixels.
150Updates the dimensions of your app’s iframe. This is the primary method for controlling the size of your app’s view.
Example:
// Request to resize the iframe to 400px wide and 500px tallAP.resize('400px', '500px');
// You can also use percentagesAP.resize('100%', '300px');width | Type: Required: Yes Description: The desired width (e.g., |
height | Type: Required: Yes Description: The desired height (e.g., |
Retrieves the current dimensions of the app’s iframe.
Example:
const currentSize = AP.size();console.log("Current width:", currentSize.w);console.log("Current height:", currentSize.h);{ "w": "100%", "h": 926}w | Type: Description: The current width of the iframe (e.g., |
h | Type: Description: The current height of the iframe in pixels. |
AP.registerIntersectionObserver(elementId, callback)
Section titled “AP.registerIntersectionObserver(elementId, callback)”Registers an intersection observer for an element within your app’s iframe. This allows you to detect when an element becomes visible or hidden as the user scrolls.
Example:
// Assuming you have an element: <div id="my-element"></div>AP.registerIntersectionObserver('my-element', function(entry) { if (entry.isIntersecting) { console.log('Element is now visible!'); } else { console.log('Element is hidden.'); }});elementId | Type: Required: Yes Description: The |
callback | Type: Required: Yes Description: A callback that fires when the element’s visibility changes. It receives an
|
These methods allow your app to control navigation within Crowdin, such as redirecting the user to a new page or closing the app’s view.
Redirects the user’s entire browser window to a different page within Crowdin.
Example (Crowdin):
// Redirects to the user's account settingsAP.redirect('/settings#account');
// Redirects to a project's Activity tabAP.redirect('/project/my-project/activity-stream');
// Redirects to the Store with queryParamsAP.redirect('/store/apps', {'a': 123});Example (Crowdin Enterprise):
// Redirects to the user's account settingsAP.redirect('/u/user_settings');
// Redirects to a project's Activity tabAP.redirect('/u/projects/15/activity');
// Redirects to the Store with queryParamsAP.redirect('u/marketplace/apps', {'a': 123});path | Type: Required: Yes Description: The relative path within Crowdin to redirect to. This path is different for Crowdin and Crowdin Enterprise. |
queryParams | Type: Required: No Description: An optional object of key-value pairs to be added as URL search parameters. |
Closes the modal window that the app is currently running in.
Example:
// Close the modal this app is running inAP.closeAppModal();Closes the app’s view when it is opened from the top navigation bar (the “navbar”).
Example:
// Close the app's panelAP.closeNavbarExtension();These methods are used by apps that render custom forms or require schema-based data, such as custom workflow steps in Crowdin Enterprise.
Retrieves the current data from the app’s form. This method is typically called by Crowdin when a user attempts to proceed from a custom app screen.
Example:
AP.getFormData(function(formData) { if (formData) { console.log("Current form data:", formData); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives the form data object
or |
The payload is entirely dependent on the app’s form data.
{ "custom_field": "some-value", "another_setting": true}The structure of this object is defined by your app.
Notifies Crowdin that the data in your app’s form has changed.
Example:
// Call this inside your app when a form field changesconst myFormData = { custom_field: "new-value" };AP.formDataUpdated(myFormData);detail | Type: Required: Yes Description: The object containing the new state of your form data. |
Retrieves the initial data provided by Crowdin to render your app’s UI. This is often used in custom workflow steps that require task-specific data.
Example:
AP.getRenderData(function(renderData) { if (renderData) { console.log("Initial data for rendering:", renderData); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives the render data
object or an empty object |
The payload is dynamic and depends on the app’s context.
{ "task_id": 123, "file_ids": [10, 11, 12]}The structure of this object is dynamic and defined by the context in which the app is launched.
Retrieves the form schema defined for the app. This is typically used by apps that render a UI based on a schema provided by Crowdin.
Example:
AP.getSchema(function(schema) { if (schema) { console.log("Form schema:", schema); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives the schema object or
|
The payload is a form schema object, often in JSON Schema format.
{ "type": "object", "properties": { "custom_field": { "type": "string", "title": "Custom Field" } }}The structure of this object is dynamic and defined by the app’s configuration.
These methods allow your app to get information from and perform actions in the Editor UI. They are available only when your app is loaded within the Crowdin Editor (e.g., in the side panel) and are all called via the AP.editor object.
This group of methods allows your app to read information about the strings and files currently being viewed in the Editor, as well as change the file selection.
Retrieves a data object for the currently active (highlighted) source string in the Editor.
Example:
AP.editor.getString(function(stringData) { if (stringData) { console.log("Active string ID:", stringData.id); } else { console.log("No string is currently active."); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one
|
{ "id": 1568759, "identifier": "welcome.key", "text": "Welcome!", "context": "Main screen welcome message", "max_length": 0, "file": { "id": 15385, "name": "google_play.xml" }}id | Type: Description: The unique numeric ID of the source string. |
identifier | Type: Description: The key or identifier of the string (e.g., |
text | Type: Description: The full text of the source string. |
context | Type: Description: The context associated with the string. |
max_length | Type: Description: The maximum allowed length for the translation ( |
file | Type: Description: An object containing information about the file this string belongs to. |
file.id | Type: Description: The unique ID of the file. |
file.name | Type: Description: The name of the file. |
Retrieves an array of data objects for all strings currently visible in the string list (respecting the current file, filter, and page).
Example:
AP.editor.getStringsList(function(strings) { if (strings && strings.length > 0) { console.log("Total strings in list:", strings.length); console.log("First string:", strings[0]); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives an array of
|
[ { "id": 1569759, "project_id": "844514", "text": "Welcome!", "key": "welcome", "file_id": 15411 }, { "id": 1569761, "project_id": "844514", "text": "Save as...", "key": "save_as", "file_id": 15411 }]id | Type: Description: The unique numeric ID of the source string. |
project_id | Type: Description: The ID of the project this string belongs to. |
text | Type: Description: The text of the source string. |
key | Type: Description: The key or identifier of the string. |
file_id | Type: Description: The unique ID of the file this string belongs to. |
Retrieves an array of objects for all strings that are currently selected (checked) by the user.
Example:
AP.editor.getSelectedStrings(function(selectedData) { if (selectedData && selectedData.length > 0) { console.log("Selected strings count:", selectedData.length); console.log("First selected string text:", selectedData[0].string.text); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives an array of
|
[ { "string": { "id": 1569759, "identifier": "welcome", "text": "Welcome!", "context": "welcome", "max_length": 0, "file": { "id": 15411, "name": "crowdin_sample_android.xml" } }, "translations": { "fr": [] } }, { "string": { "id": 1569761, "identifier": "save_as", "text": "Save as...", "context": "save_as", "max_length": 0, "file": { "id": 15411, "name": "crowdin_sample_android.xml" } }, "translations": { "fr": [ { "id": 690949, "text": "Sauvegarder sous..." } ] } }]string | Type: Description: The source string object. See the structure from |
translations | Type: Description: An object containing translations for the string, keyed by language ID. |
translations.[language_id] | Type: Description: An array of translation objects for the specified target language (e.g.,
|
Retrieves an array of data objects for all files that are currently selected (checked) in the file tree.
Example:
AP.editor.getSelectedFiles(function(files) { if (files && files.length > 0) { console.log("Selected files count:", files.length); console.log("First selected file:", files[0].name); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives an array of
|
[ { "id": "15411", "is_plain_text": true, "type": "android10", "status": "1", "parent_id": "0", "node_type": "1", "created": "2025-11-07 14:53:28", "extension": "xml", "priority": "1", "name": "crowdin_sample_android.xml", "upload_ready": 1, "export_ready": 1, "export_xliff_ready": 1, "can_change": 1, "plural_support": 1, "excluded_languages": [], "html_preview": false, "identifier_required": 1, "total": 45, "translated": 0, "approved": 0, "preTranslated": 0, "translated_percent": 0, "approved_percent": 0 }]id | Type: Description: The unique ID of the file. |
name | Type: Description: The name of the file. |
type | Type: Description: The file type identifier (e.g., |
node_type | Type: Description: The type of node in the file tree (e.g., |
total | Type: Description: The total number of strings in the file. |
translated | Type: Description: The number of translated strings in the file (for the current language). |
approved | Type: Description: The number of approved strings in the file (for the current language). |
AP.editor.isMultipleFilesSelected(callback)
Section titled “AP.editor.isMultipleFilesSelected(callback)”Checks if more than one file is currently selected (checked) in the file tree.
Example:
AP.editor.isMultipleFilesSelected(function(isMultiple) { if (isMultiple) { console.log("Multiple files are selected."); } else { console.log("Only one file (or no files) is selected."); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives a
|
This method returns a plain boolean.
trueChanges the Editor view to focus on a single, different file.
Example:
// Switch the Editor to show strings from file with ID 15409AP.editor.changeFile('15409');fileId | Type: Required: Yes Description: The ID of the file you want to switch to. |
Selects multiple files in the file tree. This is the programmatic equivalent of a user checking multiple file checkboxes.
Example:
// Select two specific files in the file listAP.editor.changeFiles(['15409', '15411']);fileIds | Type: Required: Yes Description: An array of file IDs (as strings or integers) to select. |
AP.editor.getUnsavedSourceStrings(callback)
Section titled “AP.editor.getUnsavedSourceStrings(callback)”Retrieves a list of source strings that have unsaved changes.
Example:
AP.editor.getUnsavedSourceStrings(function(unsavedStrings) { if (unsavedStrings) { console.log("Unsaved strings:", unsavedStrings); }});callback | Type: Required: Yes Description: A callback function to handle the response. It receives an array of unsaved
string objects or |
This group of methods allows you to read translation suggestions, as well as write or modify text in the Editor’s translation area.
Retrieves an array of all translations and suggestions (from users, TM, and MT) for the currently active source string.
Example:
AP.editor.getTranslations(function(translations) { if (translations && translations.length > 0) { console.log("Total translations/suggestions:", translations.length); console.log("First translation author:", translations[0].author.login); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives an array of
|
[ { "id": 690949, "string_id": 1569689, "text": "Translation text", "target_language_id": "fr", "votes_rating": 0, "approved": false, "author": { "id": "12729493", "login": "example_user", "name": "Example User", "avatar_url": "https://.../avatar.png" }, "created_at": "2025-11-07T08:19:10-05:00" }]id | Type: Description: The unique numeric ID of the translation. |
string_id | Type: Description: The ID of the source string this translation belongs to. |
text | Type: Description: The translation text. |
target_language_id | Type: Description: The ID of the language this translation is for (e.g., |
votes_rating | Type: Description: The current vote score for this translation. |
approved | Type: Description: |
author | Type: Description: An object containing information about the user who authored the translation. |
author.id | Type: Description: The unique ID of the author. |
author.login | Type: Description: The author’s login name. |
created_at | Type: Description: The ISO 8601 timestamp of when the translation was created. |
Retrieves a single TranslationObject for the “top” translation of the currently active string (e.g., the approved translation or the one with the most votes).
Example:
AP.editor.getTopTranslation(function(topTranslation) { if (topTranslation) { console.log("Top translation text:", topTranslation.text); } else { console.log("No translations exist for this string yet."); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one
|
{ "id": 690949, "string_id": 1569689, "text": "This is the top translation.", "target_language_id": "fr", "votes_rating": 1, "approved": true, "author": { "id": "12729493", "login": "example_user" }, "created_at": "2025-11-07T08:19:10-05:00"}This method returns a single TranslationObject. See the structure table for AP.editor.getTranslations for a full list of properties.
Sets or overwrites the text in the Editor’s main translation text area for the active string.
Example:
// Set the translation text to "Hello world"AP.editor.setTranslation("Hello world");text | Type: Required: Yes Description: The text to insert into the translation area. |
Appends text to the end of the existing text in the Editor’s translation text area.
Example:
// If the text area contains "Hello", this will change it to "Hello world"AP.editor.appendTranslation(" world");text | Type: Required: Yes Description: The text to append. |
Clears all text from the Editor’s translation text area for the active string.
Example:
AP.editor.clearTranslation();Sets the browser’s focus on the Editor’s translation text area.
Example:
AP.editor.setFocus();AP.editor.setUnsavedSuggestion(suggestion)
Section titled “AP.editor.setUnsavedSuggestion(suggestion)”Sets an “unsaved suggestion” for a specific string. This is used to programmatically add a translation without saving it, often used in the Multilingual view.
Example:
AP.editor.setUnsavedSuggestion({ id: 1569759, // The numeric or string ID of the phrase text: 'My unsaved suggestion', // The translation text languageId: 'fr', // Target language code pluralId: 1, // Optional: Specific plural form ID translationId: 45678 // Optional: ID if editing an existing translation});suggestion | Type: Required: Yes Description: An object containing the suggestion details. See the |
id | Type: Required: Yes Description: The numeric or string ID of the source string (phrase). |
text | Type: Required: Yes Description: The translation text. |
languageId | Type: Required: Yes Description: The ID of the target language (e.g., |
pluralId | Type: Required: No Description: The ID of the plural form (e.g., |
translationId | Type: Required: No Description: The ID of an existing translation if you are editing it. |
AP.editor.setUnsavedSuggestions(suggestions)
Section titled “AP.editor.setUnsavedSuggestions(suggestions)”Sets multiple “unsaved suggestions” at once.
Example:
AP.editor.setUnsavedSuggestions([ { id: 1569759, text: 'Suggestion 1', languageId: 'fr', pluralId: '1' }, { id: 1569761, text: 'Suggestion 2', languageId: 'fr', pluralId: null }]);suggestions | Type: Required: Yes Description: An array of suggestion objects. See the |
AP.editor.removeUnsavedSuggestions(suggestions)
Section titled “AP.editor.removeUnsavedSuggestions(suggestions)”Removes one or more “unsaved suggestions”.
Example:
// Remove a specific unsaved suggestionAP.editor.removeUnsavedSuggestions([ { id: 1569759, text: 'Suggestion 1', languageId: 'fr', pluralId: '1' }]);suggestions | Type: Required: Yes Description: An array of suggestion objects to remove. The format is identical to |
AP.editor.applyUnsavedTranslations(method, data)
Section titled “AP.editor.applyUnsavedTranslations(method, data)”Applies (saves) all unsaved translations based on the provided method.
Example:
// Apply unsaved translations only for the selected stringsAP.editor.applyUnsavedTranslations('selectedStrings', null);
// Apply unsaved translations for a specific list of string IDsAP.editor.applyUnsavedTranslations('providedStrings', [1569759, 1569761]);method | Type: Required: Yes Description: The method to use for applying translations. Allowed values: |
data | Type: Required: Yes Description: An array of numeric string IDs. This is only used when |
This group of methods allows your app to read and control the string filters used in the Editor, including basic filters, the Advanced Filter, and CroQL queries.
Retrieves a complete list of all available basic filters, including their names and numeric IDs.
Example:
AP.editor.getFiltersList(function(filters) { console.log("Available filters:", filters);});callback | Type: Required: Yes Description: A callback function that handles the response. It receives an array of
|
[ { "name": "Show All", "value": 3 }, { "name": "Untranslated", "value": 2 }, { "name": "Not Approved", "value": 5 }, { "name": "Approved", "value": 4 }, { "name": "Machine Translations" }, { "name": "All", "value": 10 }, { "name": "All, Untranslated First", "value": 0 }]name | Type: Description: The display name of the filter (e.g., “Untranslated”). |
value | Type: Description: The numeric ID of the filter. This value is used by
|
Retrieves the numeric ID of the currently active basic filter (e.g., “Untranslated”, “Approved”).
Example:
AP.editor.getFilter(function(filterId) { console.log("Current filter ID:", filterId); // Example output: 0 (for "All, Untranslated First")});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one argument: an
|
This method returns a plain integer.
0Applies a basic filter to the string list using its numeric ID.
Example:
// Filter the list to show only "Untranslated" strings (ID 2)AP.editor.setFilter(2);filterNumber | Type: Required: Yes Description: The numeric ID of the filter to apply. See |
Here are some of the most common default filter IDs:
- 0: All, Untranslated First
- 2: Untranslated
- 3: Show All
- 4: Approved
- 5: Translated, Not Approved
- 7: With Comments
- 10: Translated by TM or MT
- 12: Advanced Filter
- 30: Translated by TM
- 31: Translated by MT
Retrieves an object representing the current state of the “Advanced Filter”.
Example:
AP.editor.getCustomFilter(function(customFilter) { if (customFilter) { console.log("Current advanced filter settings:", customFilter); console.log("Filtering by translation status:", customFilter.translations); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one
|
{ "translations": "untranslated", "labels": [123, 456], "label_match_rule": "any", "comments": "have_comments", "croql_expression": "", "ai_query": ""}The CustomFilterObject contains all fields available in the Editor’s Advanced Filter dialog. Below are some key properties:
translations | Type: Allowed values: Description: Filters strings based on their translation status. |
comments | Type: Allowed values: Description: Filters strings based on the presence of comments. |
labels | Type: Description: An array of label IDs to filter by. |
croql_expression | Type: Description: A custom CroQL expression for advanced filtering. |
Applies an “Advanced Filter” to the string list by providing a filter object.
Example:
// Filter for untranslated strings with specific labelsAP.editor.setCustomFilter({ translations: 'untranslated', labels: [123, 456], label_match_rule: 'any'});customFilter | Type: Required: Yes Description: A |
Click to view all available filter properties
{ added_from: '', added_to: '', updated_from: '', updated_to: '', translations: '', // 'translated', 'untranslated' duplicates: '', tm_and_mt: '', pre_translation: '', approvals: '', comments: '', // 'have_comments', 'no_comments' screenshots: '', visibility: '', qa_issues: '', labels: [], label_match_rule: 'any', // 'all', 'any' exclude_labels: [], exclude_label_match_rule: 'all', string_type: '', votes: '', votes_count: null, approvals_count_select: '', approvals_count: null, translated_by_user: '', not_translated_by_user: '', approved_by_user: '', not_approved_by_user: '', sort_method: 0, sort_ascending: 1, croql_expression: '', ai_query: ''}Resets the “Advanced Filter” to its default (empty) state.
Example:
AP.editor.resetCustomFilter();Retrieves the currently active CroQL filter query as a string.
Example:
AP.editor.getCroqlFilter(function(croqlQuery) { if (croqlQuery) { console.log("Current CroQL query:", croqlQuery); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one
|
This method returns a plain string.
"text = "Welcome!""Applies a CroQL filter to the string list.
Example:
// Filter strings where the text is "Welcome!"AP.editor.setCroqlFilter("text = 'Welcome!'");croql | Type: Required: Yes Description: A valid CroQL query string. |
Resets the CroQL filter to its default (empty) state.
Example:
AP.editor.resetCroqlFilter();This group of methods allows you to read and control the Editor’s state, such as the current view mode, page, selected language, or search query.
Retrieves the name of the currently active Editor mode.
Example:
AP.editor.getMode(function(modeName) { console.log("Current mode:", modeName); // Example output: "translate"});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one argument: a
|
This method returns a plain string.
"translate"Type: string
Allowed values: translate, proofread, review,
multilingual
Switches the Editor to a different mode.
Example:
// Switch the Editor to Proofreading modeAP.editor.setMode('proofread');modeName | Type: Required: Yes Description: The name of the mode to switch to. Allowed values: |
Retrieves the current page number of the string list.
Example:
AP.editor.getPage(function(pageNumber) { console.log("Current page:", pageNumber); // Example output: 1});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one argument: an
|
This method returns a plain integer.
1Changes the string list to a specific page number.
Example:
// Go to the second page of stringsAP.editor.setPage(2);pageNumber | Type: Required: Yes Description: The page number to navigate to. |
AP.editor.getProjectTargetLanguages(callback)
Section titled “AP.editor.getProjectTargetLanguages(callback)”Retrieves a list of the project’s target languages that are available to the current user in the Editor.
Example:
AP.editor.getProjectTargetLanguages(function(languages) { if (languages && languages.length > 0) { console.log("Available languages:", languages); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives an array of
|
[ { "id": "2", "name": "French", "internal_code": "fr", "code": "fr", "preferred": false }, { "id": "3", "name": "German", "internal_code": "de", "code": "de", "preferred": true }]id | Type: Description: The unique ID of the language (e.g., |
name | Type: Description: The display name of the language (e.g., “French”). |
code | Type: Description: The language code (e.g., |
AP.editor.setTargetLanguage(languageIds, [callback])
Section titled “AP.editor.setTargetLanguage(languageIds, [callback])”Switches the Editor to a different target language in Side-by-Side and Comfortable modes or sets the active languages in Multilingual mode.
Example (Side-by-Side and Comfortable Modes):
// Switch the Editor to German (ID "11")AP.editor.setTargetLanguage('11');Example (Multilingual Mode):
// Set the active languages to German (ID "11") and French (ID "2")AP.editor.setTargetLanguage(['11', '2']);languageIds | Type: Required: Yes Description: The string ID (e.g., |
callback | Type: Required: No Description: An optional callback that returns an error message if any requested language IDs were not found. |
Performs a search in the Editor for the specified text.
Example:
// Perform a simple search for the word "Welcome"AP.editor.search("Welcome");
// Perform a case-sensitive searchAP.editor.search("Welcome", { caseSensitive: true, search_option: 1 });text | Type: Required: Yes Description: The text to search for. |
options | Type: Required: No Description: An object containing search options. See the |
searchStrict | Type: Description: If |
searchFullMatch | Type: Description: If |
caseSensitive | Type: Description: If |
search_option | Type: Description: Defines the search scope. |
This group of methods allows your app to display feedback messages (like notices, successes, or errors) to the user and manage notification badges on your app’s icon.
Displays a yellow “notice” message bar at the top of the Editor.
Example:
AP.editor.noticeMessage("This is a test notification.");message | Type: Required: Yes Description: The text to display in the message bar. |
Displays a green “success” message bar at the top of the Editor.
Example:
AP.editor.successMessage("The operation was successful!");message | Type: Required: Yes Description: The text to display in the message bar. |
Displays a red “error” message bar at the top of the Editor.
Example:
AP.editor.errorMessage("An error occurred. Please try again.");message | Type: Required: Yes Description: The text to display in the message bar. |
AP.editor.setApplicationNotification(count)
Section titled “AP.editor.setApplicationNotification(count)”Sets a blue notification badge with a number on your app’s icon in the Editor’s side panel.
Example:
AP.editor.setApplicationNotification(2);count | Type: Required: Yes Description: The number to display in the notification badge. |
Removes the notification badge from your app’s icon.
Example:
AP.editor.clearApplicationNotification();This group of methods allows your app to read information about the project’s workflow and control the user’s state within that workflow.
Retrieves a list of all workflow steps available in the current project for the user.
Example:
AP.editor.getWorkflowSteps(function(steps) { if (steps && steps.length > 0) { console.log("Available workflow steps:", steps); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives an array of
|
[ { "id": 752, "title": "Translation", "type": "Translate", "editor_mode": "translate", "approving_available": true, "source_language": { "id": 52, "name": "English", "code": "en" } }, { "id": 753, "title": "Proofreading", "type": "Proofread", "editor_mode": "proofread", "approving_available": true, "source_language": { "id": 52, "name": "English", "code": "en" } }]id | Type: Description: The unique numeric ID of the workflow step. |
title | Type: Description: The display name of the workflow step (e.g., “Translation”). |
type | Type: Description: The type of step (e.g., “Translate”, “Proofread”). |
editor_mode | Type: Description: The corresponding Editor mode for this step. |
approving_available | Type: Description: |
source_language | Type: Description: An object containing details about the source language. |
AP.editor.getWorkflowStepStatusFilter(callback)
Section titled “AP.editor.getWorkflowStepStatusFilter(callback)”Retrieves the currently active filter for workflow step status at the current workflow step.
Example:
AP.editor.getWorkflowStepStatusFilter(function(status) { console.log("Current step status filter:", status); // Example output: "ALL"});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one
|
This method returns a plain string.
"ALL"Type: string
Allowed values: ALL, ToDo, Pending, Done
Switches the Editor to a different workflow step.
Example:
// Switch the Editor to workflow step with ID 753AP.editor.setWorkflowStep(753);stepId | Type: Required: Yes Description: The ID of the workflow step to switch to. See
|
AP.editor.setWorkflowStepStatusFilter(status)
Section titled “AP.editor.setWorkflowStepStatusFilter(status)”Sets the filter for workflow step status at the current workflow step.
Example:
// Filter to show only strings that are "DONE"AP.editor.setWorkflowStepStatusFilter('DONE');status | Type: Required: Yes Description: The status to filter by. Allowed values: |
These methods allow your app to interact with the “AI Assistant” panel within the Editor.
Starts a new, empty conversation in the AI Assistant panel.
Example:
// Clear the current AI chat and start a new oneAP.editor.ai.startNewConversation();Adds a new message from the user to the current AI Assistant conversation and waits for a response.
Example:
// Send a message to the AI AssistantAP.editor.ai.addMessage("Hello AI, please explain this string.");messageText | Type: Required: Yes Description: The text content of the message to send to the AI Assistant. |
These methods allow your app to get the text currently selected by the user’s cursor in the source string area or the translation text area.
AP.editor.source.getSelectedText(callback)
Section titled “AP.editor.source.getSelectedText(callback)”Retrieves the text currently selected by the user’s cursor within the source string area.
Example:
AP.editor.source.getSelectedText(function(selectedText) { if (selectedText) { console.log("User selected this source text:", selectedText); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one argument: a
|
This method returns a plain string of the selected text, or null if no text is selected.
"Selected source text"AP.editor.textarea.getSelectedText(callback)
Section titled “AP.editor.textarea.getSelectedText(callback)”Retrieves the text currently selected by the user’s cursor within the translation text area.
Example:
AP.editor.textarea.getSelectedText(function(selectedText) { if (selectedText) { console.log("User selected this translation text:", selectedText); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one argument: a
|
This method returns a plain string of the selected text, or null if no text is selected.
"My selected translation"This group of methods provides advanced integration points for customizing the Editor’s native behavior, such as adding custom context menus, managing hotkeys, and applying custom styles.
AP.editor.registerContextMenuAction(action, callback)
Section titled “AP.editor.registerContextMenuAction(action, callback)”Registers a custom item in the Editor’s context menu (the menu that appears on right-click).
You must define the action object, and the callback will return the same object augmented with an eventSubscriptionId. You then use AP.events.on to listen for clicks on that ID.
Example:
// 1. Define and register the context menu itemAP.editor.registerContextMenuAction({ type: 'textarea-context-menu', name: 'My Custom Action'}, function(action) {
// 2. Listen for clicks on this specific item AP.events.on(action.eventSubscriptionId, function() { console.log(`'${action.name}' was clicked!`); AP.editor.noticeMessage("Custom action triggered!"); });});action | Type: Required: Yes Description: The configuration object for the action. See the |
callback | Type: Required: Yes Description: A callback that receives the action object back, now including an
|
type | Type: Required: Yes Description: The type of context menu where the action will be displayed. Possible values:
|
name | Type: Required: Yes Description: The text label that will be displayed in the context menu. |
children | Type: Required: No Description: An optional array of child |
The callback receives the action object back, augmented with an eventSubscriptionId.
{ "type": "textarea-context-menu", "name": "My Test Action", "eventSubscriptionId": "context.menu.click:GGChNhE"}eventSubscriptionId | Type: Description: The unique ID for this menu item. Use this ID with |
…plus all properties from the | |
Simple action for the source string context menu
AP.editor.registerContextMenuAction({ type: 'source-string-context-menu', name: 'Start new AI conversation'}, function(action) { AP.events.on(action.eventSubscriptionId, () => { // Start a new AI conversation when clicked AP.editor.ai.startNewConversation(); console.log('Starting new AI conversation...'); });});Action with a submenu
AP.editor.registerContextMenuAction({ type: 'source-string-context-menu', name: 'My AI Actions', children: [ { name: 'Explain selection' }, { name: 'Check grammar' } ]}, function(action) { // Handle the child menu items if (action.children) { action.children.forEach((childAction) => { AP.events.on(childAction.eventSubscriptionId, () => { // Add the logic that should happen on click console.log(`'${childAction.name}' was clicked.`); }); }); }});Action for selected text in the translation area
AP.editor.registerContextMenuAction({ type: 'textarea-context-menu', name: 'Send selected text to AI'}, function(action) { AP.events.on(action.eventSubscriptionId, () => { // Get the selected text and send it AP.editor.textarea.getSelectedText(function(text) { if (text) { AP.editor.ai.addMessage(text); } }); });});Retrieves a string containing all hotkeys currently active in the Editor.
Example:
AP.editor.getHotKeys(function(hotkeys) { console.log("Active hotkeys:", hotkeys);});callback | Type: Required: Yes Description: A callback function that handles the response. It receives one argument: a
|
This method returns a plain string with hotkeys separated by commas.
"Command+Enter,Command+[,Command+],Control+Shift+C,..."AP.editor.propagateHotKeyPress(hotKeyPressed)
Section titled “AP.editor.propagateHotKeyPress(hotKeyPressed)”Manually propagates a hotkey press from your app’s iframe up to the main Editor. This is useful if your app captures a key event (like “Enter”) that you also want the Editor to react to.
Example:
// Tell the Editor that the "Command+Enter" hotkey was pressedAP.editor.propagateHotKeyPress('Command+Enter');hotKeyPressed | Type: Required: Yes Description: The hotkey string that was pressed (e.g., |
AP.editor.applyCustomThemeStyle(theme, callback)
Section titled “AP.editor.applyCustomThemeStyle(theme, callback)”Applies a custom theme configuration to the Editor’s UI. This allows for deep customization of colors, backgrounds, and element highlights.
Example:
AP.editor.applyCustomThemeStyle({ themeMode: 'dark', // Context mode ('light' or 'dark') primaryAccent: '#35a1ff', base: { baseBackground: '#16191d', stringStatus: { translated: '#74bb02', approved: '#35a1ff' }, highlights: { placeholderColor: '#35a1ff', placeholderBg: 'rgba(53, 161, 255, 0.1)', tagColor: '#74bb02', tagBg: 'rgba(116, 187, 2, 0.1)', nonePrintableCharacterColor: '#3eb17f', findAndReplaceHighlightBg: '#cc9a06', specialLightColor: '#35a1ff', specialLightBg: 'rgba(53, 161, 255, 0.05)' } }, accents: { info: { accentColor: '#35a1ff' }, danger: { accentColor: '#ff4444' }, warning: { accentColor: '#cc9a06' }, success: { accentColor: '#74bb02' } }}, (result) => { if (result) { console.error('Error applying theme:', result); } else { console.log('Theme applied successfully'); }});theme | Type: Required: Yes Description: A |
callback | Type: Required: No Description: A callback function that handles the response. It receives an error message
string if the application fails, or |
Removes all custom CSS applied by AP.editor.applyCustomThemeStyle.
Example:
AP.editor.resetCustomThemeStyle();These methods allow your app to open and close modal windows from within the Editor.
Opens one of your app’s defined “modal” modules.
Example:
// Open a modal moduleAP.editor.openModal({ resource: 'my-modal-key', size: 'medium'}, function(success) { if (success) { console.log("Modal opened successfully."); }});options | Type: Required: Yes Description: The configuration object for the modal. See the |
callback | Type: Required: No Description: An optional callback function that receives a |
resource | Type: Required: Yes Description: The |
size | Type: Required: No Description: The size of the modal window. Allowed values: |
onClose | Type: Required: No Description: An optional callback function that will be executed when the modal is closed. |
Closes the currently open modal, but only if it was opened by your app using AP.editor.openModal.
Example:
// Close the modalAP.editor.closeModal();This group of methods allows your app to interact with the Crowdin project, such as navigating to different project pages or opening the Editor. They are all called via the AP.project object.
Redirects the user to a different page within the current project.
Example:
// Redirects to the project's Activity tabAP.project.redirect('/activity-stream');
// Forces a full-page reload to the project's rootAP.project.redirect('/', true);path | Type: Required: Yes Description: The relative path within the project to redirect to (e.g., |
hardRedirect | Type: Required: No Description: If set to |
Opens a built-in Crowdin modal dialog.
Example:
// Open the "Pre-translation via MT" modalAP.project.openModal('mt-pre-translation');modalName | Type: Required: Yes Description: The name of the built-in modal to open. Allowed values: |
AP.project.openEditor(fileId, [view], [languageCode])
Section titled “AP.project.openEditor(fileId, [view], [languageCode])”Opens the Crowdin Editor for a specific file.
Example:
// Open a specific file in the default viewAP.project.openEditor('15411');
// Open a file in Multilingual mode for a specific languageAP.project.openEditor('15411', 'multilingual', 'de');fileId | Type: Required: Yes Description: The ID of the file to open. |
view | Type: Required: No Description: The Editor mode to open (e.g., |
languageCode | Type: Required: No Description: The language code (e.g., |
Navigates the user to the appropriate tab based on the project type (Translations for file-based projects or Download for string-based projects) and triggers a preview download (in CSV or XLSX format).
Example:
// Trigger a preview download in CSV formatAP.project.previewTranslations('csv');action | Type: Required: Yes Description: The format of the preview to download. Allowed values: |
Retrieves the configuration object for project tabs, indicating which tabs are currently visible or hidden in the project context.
Example:
AP.project.getTabsConfiguration(function(config) { if (config) { console.log("Current tabs configuration:", config); }});callback | Type: Required: Yes Description: A callback function that handles the response. It receives an
|
This method returns an array of objects.
[ { "identifier": "home", "visible": true }, { "identifier": "sources", "visible": true },41 collapsed lines
{ "identifier": "translations", "visible": true }, { "identifier": "screenshots", "visible": true }, { "identifier": "tasks", "visible": true }, { "identifier": "members", "visible": true }, { "identifier": "integrations", "visible": true }, { "identifier": "reports", "visible": false }, { "identifier": "activity-stream", "visible": true }, { "identifier": "discussions", "visible": true }, { "identifier": "tools", "visible": true }, { "identifier": "test_app¦test_app-project-menu", "visible": true }, { "identifier": "settings", "visible": true }]AP.project.saveTabsConfiguration(params, callback)
Section titled “AP.project.saveTabsConfiguration(params, callback)”Saves a new configuration for project tabs. This allows you to programmatically show or hide specific tabs within the project context.
Example:
const newConfig = [ { "identifier": "home", "visible": true }, { "identifier": "sources", "visible": true },40 collapsed lines
{ "identifier": "translations", "visible": true }, { "identifier": "screenshots", "visible": true }, { "identifier": "tasks", "visible": false }, { "identifier": "members", "visible": false }, { "identifier": "integrations", "visible": true }, { "identifier": "reports", "visible": false }, { "identifier": "activity-stream", "visible": true }, { "identifier": "discussions", "visible": true }, { "identifier": "tools", "visible": true }, { "identifier": "test_app¦test_app-project-menu", "visible": true }, { "identifier": "settings", "visible": true }];
AP.project.saveTabsConfiguration({ tabs_configuration: newConfig }, function(success) { if (success) { console.log("Configuration saved successfully."); }});params | Type: Required: Yes Description: An object containing the new configuration. See the |
callback | Type: Required: No Description: An optional callback function that receives a |
tabs_configuration | Type: Required: Yes Description: An array of tab configuration objects. See |
This group of methods allows your app to interact with the user’s account profile pages, outside of a project. They are all called via the AP.profile object.
Redirects the user to a different page within their “Profile” area.
Example:
// Redirects the user to their "Tasks" pageAP.profile.redirect('/tasks');path | Type: Required: Yes Description: The relative path within the user’s profile to redirect to (e.g.,
|
These methods are used to control modal windows (e.g., setting a size of a modal from within its own iframe).
Updates the dimensions and scroll behavior of the modal window your app is currently running in.
Example:
// Update the modal size and scroll behaviorAP.modal.setSize({ width: "600px", height: "600px", hideXScrolls: true, // Optional, default: true hideYScrolls: false // Optional, default: false});options | Type: Required: Yes Description: An object containing the size and scroll settings. See the |
width | Type: Required: Yes Description: The desired width (e.g., |
height | Type: Required: Yes Description: The desired height (e.g., |
hideXScrolls | Type: Required: No Description: Whether to hide horizontal scrollbars. Default is |
hideYScrolls | Type: Required: No Description: Whether to hide vertical scrollbars. Default is |
These methods allow your app to listen and react to events happening within the Crowdin UI (e.g., when a user changes a string or saves a translation), as well as to trigger your own custom events. They are all called via the AP.events object.
Read more about Supported Events.
Subscribes a listener to an event. This is the primary method for listening to both Crowdin UI events (e.g., string.change) and custom internal events emitted by your app or the library.
Example:
// Listen for the 'string.change' event from CrowdinAP.events.on('string.change', function(stringData) { console.log("User switched to string ID:", stringData.id);});eventName | Type: Required: Yes Description: The name of the event to listen for (e.g., |
callback | Type: Required: Yes Description: The function to execute when the event fires. It receives a data payload object specific to the event. |
Subscribes a listener to an event, but the listener is automatically removed after it has been executed one time.
Example:
// Run this code only the next time a translation is addedAP.events.once('translation.added', function(translation) { console.log("A translation was added:", translation.text);});eventName | Type: Required: Yes Description: The name of the event to listen for. |
callback | Type: Required: Yes Description: The function to execute one time when the event fires. |
Removes a specific event listener that was previously registered with AP.events.on or AP.events.once.
Example:
const myListener = function(data) { console.log(data); };
// Start listeningAP.events.on('string.change', myListener);
// Stop listeningAP.events.off('string.change', myListener);eventName | Type: Required: Yes Description: The name of the event to unsubscribe from. |
callback | Type: Required: Yes Description: The exact same function object that was used to register the listener. |
Removes all event listeners for a specific event.
Example:
// Stop all listeners for the 'string.change' eventAP.events.offAll('string.change');eventName | Type: Required: Yes Description: The name of the event for which to remove all listeners. |
Subscribes a listener that fires for any event. This is useful for debugging to see all events passing through the system.
Example:
AP.events.onAny(function(eventName, eventData) { console.log("Event fired:", eventName, "with data:", eventData);});callback | Type: Required: Yes Description: A callback function that receives two arguments: the |
Removes a specific listener that was registered with AP.events.onAny.
Example:
const myDebugListener = function(eventName, eventData) { /* ... */ };AP.events.onAny(myDebugListener);
// Later, to stop listeningAP.events.offAny(myDebugListener);callback | Type: Required: Yes Description: The exact same function object that was used to register the listener. |
Fires a custom event within your app. Any listeners registered with AP.events.on will be triggered.
Example:
// Fire a custom event with some dataAP.events.emit('my-custom-event', { status: 'updated' });eventName | Type: Required: Yes Description: The name of the custom event to fire. |
data | Type: Required: No Description: An optional data payload to send to the event listeners. |
Use these event names with the AP.events.on() method to listen for actions happening in the Crowdin UI.
| Event | Details & Payload |
|---|---|
string.change | Fires when a user switches from one source string to another. Payload: A |
string.selected | Fires when a user selects or deselects strings (using checkboxes in Side-by-Side view). Payload: An array of |
textarea.edited | Fires when a user makes any change (types, deletes, pastes) in the translation text area. Payload: An object containing the string data, the |
translation.added | Fires when a user saves a new translation. Payload: A |
translation.deleted | Fires when a user deletes a translation. Payload: An object containing the |
translation.restored | Fires when a user restores a deleted translation. Payload: The restored |
translation.vote | Fires when a user votes (up or down) for a translation. Payload: The updated |
translation.approve | Fires when a user approves a translation. Payload: The updated |
translation.disapprove | Fires when a user removes an approval from a translation. Payload: The updated |
language.change | Fires when the user changes the target language in the Editor. Payload: The full |
file.change | Fires when the user switches to a different file in the Editor. Payload: The full |
theme.changed | Fires when the user changes the UI theme. Payload: A |
asset.source.preview | Fires when a source asset file is selected in the Editor (for asset-based projects). Payload: The |
asset.suggestion.preview | Fires when a suggestion asset file is selected in the Editor (for asset-based projects). Payload: An object containing |