Overview
You can create Crowdin apps that extend the functionality of Crowdin by adding new modules to the Crowdin UI. Modules are displayed in the Crowdin UI and can be used to add new features or modify existing ones.
Supported Modules
Project Integration Allows you to create and add a new integration into your Crowdin project.
File Processor Allows you to add support for new custom file formats and customize processing for supported file formats.
Other Supported Modules
The SDK supports all the other modules that are available in Crowdin:
- profile-resources-menu -
profileResourcesMenu
- organization-menu -
organizationMenu
- editor-right-panel -
editorRightPanel
- project-menu -
projectMenu
- project-menu-crowdsource -
projectMenuCrowdsource
- project-tools -
projectTools
- project-reports -
projectReports
Sample
Example of profile-resources-menu module:
const crowdinModule = require('@crowdin/app-project-module');
const configuration = { baseUrl: 'https://123.ngrok.io', clientId: 'clientId', clientSecret: 'clientSecret', name: 'Sample App', identifier: 'sample-app', description: 'Sample App description', dbFolder: __dirname, imagePath: __dirname + '/' + 'logo.png', profileResourcesMenu: { fileName: 'setup.html', uiPath: __dirname + '/' + 'public', environments: 'crowdin-enterprise' }};
crowdinModule.createApp(configuration);
Configuration
Parameter | Description | Example |
---|---|---|
imagePath | Path to the module logo (can be different image than the app logo). | __dirname + '/' + 'reports.png' |
fileName | Optional, only needed if file is not index.html . | 'reports.html' |
uiPath | Folder where UI of the module is located (js , html , css files). | __dirname + '/' + 'public' |
environments | Environment where the module should render. | crowdin / enterprise |
Combining Modules
Each module can work as an extension to other modules, being something like a configuration UI for them:
const crowdinModule = require('@crowdin/app-project-module');const app = crowdinModule.express();
const configuration = { baseUrl: 'https://123.ngrok.io', clientId: 'clientId', clientSecret: 'clientSecret', name: 'Sample App', identifier: 'sample-app', description: 'Sample App description', dbFolder: __dirname, imagePath: __dirname + '/' + 'logo.png', profileResourcesMenu: { fileName: 'setup.html', uiPath: __dirname + '/' + 'public', environments: 'crowdin' }, customMT: { translate }, onUninstall: cleanup};
const crowdinApp = crowdinModule.addCrowdinEndpoints(app, configuration);const metadataStore = crowdinModule.metadataStore;
async function cleanup(organization, allCredentials) { // Cleanup logic await crowdinApp.deleteMetadata(organization);}
async function translate(crowdinClient, context, projectId, source, target, strings) { const organization = context.jwtPayload.domain || context.jwtPayload.context.organization_id; const metadata = await metadataStore.getMetadata(organization); // do translation based on metadata const translations = ['hello', 'world']; return translations;}
// extra endpoints for resources UIapp.post('/metadata', async (req, res) => { const { context } = await crowdinApp.establishCrowdinConnection(req.query.jwt); const id = `${context.jwtPayload.context.organization_id}_${context.jwtPayload.context.project_id}`; const organization = context.jwtPayload.domain || context.jwtPayload.context.organization_id; const metadata = await metadataStore.getMetadata(organization); await crowdinApp.saveMetadata(id, req.body, organization); res.status(204).end();});
app.get('/metadata', async (req, res) => { const { context } = await crowdinApp.establishCrowdinConnection(req.query.jwt); const id = `${context.jwtPayload.context.organization_id}_${context.jwtPayload.context.project_id}`; const metadata = await metadataStore.getMetadata(id) || {}; res.status(200).send(metadata);});
app.listen(3000, () => console.log('Crowdin app started'));
Read more about App Metadata.