# Custom MT

This module helps you connect machine translation engines not yet supported by Crowdin.

[Custom MT Module](https://support.crowdin.com/developer/crowdin-apps-module-custom-mt/)

## Sample

```js ins="customMT" title="index.js"
    import crowdinModule from '@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: import.meta.dirname,
      imagePath: import.meta.dirname + '/logo.png',
      customMT: [
        {
          withContext: true,
          splitStringsIntoChunks: false,
          translate: async ({ client, context, projectId, source, target, strings }) => {
            const translations = ['hello', 'world'];

            if (source === 'fr') {
              throw 'Source language is not supported by the model';
            }

            return translations;
          },
          validate: (client) => {
            console.log('validate');
          }
        }
      ]
    };

    crowdinModule.createApp(configuration);
    ```
  ```ts ins="customMT" title="index.ts"
    import crowdinModule from '@crowdin/app-project-module';
    import type { ClientConfig } from '@crowdin/app-project-module';

    const configuration: ClientConfig = {
      baseUrl: 'https://123.ngrok.io',
      clientId: 'clientId',
      clientSecret: 'clientSecret',
      name: 'Sample App',
      identifier: 'sample-app',
      description: 'Sample App description',
      dbFolder: import.meta.dirname,
      imagePath: import.meta.dirname + '/logo.png',
      customMT: [
        {
          withContext: true,
          splitStringsIntoChunks: false,
          translate: async ({ client, context, projectId, source, target, strings }) => {
            const translations = ['hello', 'world'];

            if (source === 'fr') {
              throw 'Source language is not supported by the model';
            }

            return translations;
          },
          validate: async (client) => {
            console.log('validate');
          }
        }
      ]
    };

    crowdinModule.createApp(configuration);
    ```
  ## Configuration

| Parameter                | Description                                                                      | Allowed values  | Default value |
|--------------------------|----------------------------------------------------------------------------------|-----------------|---------------|
| `withContext`            | If `true`, strings will be received as objects.                                  | `true`, `false` | `false`       |
| `splitStringsIntoChunks` | If `false`, all strings are sent at once. By default, chunk size is 100 strings. | `true`, `false` | `true`        |

### `translate` Function

Called when the module is requested to translate strings.

#### Parameters

- `client` - Crowdin API client.
- `context` - [Context object](/app-project-module/reference/context/).
- `projectId` - Crowdin project ID (optional and could be `null`).
- `source` - Source language.
- `target` - Target language.
- `strings` - Array of strings to translate.

#### Return Value

The function must return an array of translated strings.

### `validate` Function

This function is optional. It is called when the module is initialized to validate if the module is correctly configured.

#### Parameters

- `client` - Crowdin API client.

#### Return Value

The function must return nothing.

### Multiple MT Engines

You can register multiple machine translation engines in a single app by providing an array:

```js title="index.js"
const configuration = {
  // ... other configuration
  customMT: [
    {
      name: 'Engine A',
      withContext: true,
      translate: async ({ source, target, strings }) => {
        // translation logic for engine A
        return strings.map(() => 'translation-a');
      }
    },
    {
      name: 'Engine B',
      splitStringsIntoChunks: false,
      translate: async ({ source, target, strings }) => {
        // translation logic for engine B
        return strings.map(() => 'translation-b');
      }
    }
  ]
};
```

## Error Handling

In case of an error, the function must throw an error with a message. The message will be displayed in the Crowdin UI.