# Editor Button

The module adds a button to the Crowdin Editor. Crowdin renders the button itself; a click opens one of the app's `editorRightPanel` or [modal](/app-project-module/tools/modal/) modules, or sends an `editor.button.click` event to a right panel.

[Editor Button Module](https://support.crowdin.com/developer/crowdin-apps-module-editor-button/)

## Sample

```js ins={17-32} 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',
      editorRightPanel: [{
        modes: ['translate', 'review'],
        supportsMultipleStrings: true,
        uiPath: import.meta.dirname + '/public'
      }],
      editorButton: [
        {
          key: 'open-panel',
          name: 'Open Sample App',
          location: 'header-right',
          type: 'panel',
          modes: ['translate', 'review']
        },
        {
          key: 'check-strings',
          name: 'Check selected strings',
          location: 'strings-menu',
          type: 'event',
          modes: ['translate', 'review']
        }
      ]
    };

    crowdinModule.createApp(configuration);
    ```
  ```ts ins={19-34} title="index.ts"
    import crowdinModule, { EditorMode } from '@crowdin/app-project-module';
    import type { ClientConfig } from '@crowdin/app-project-module';
    import { EditorButtonLocations, EditorButtonTypes } from '@crowdin/app-project-module/modules/editor-button';

    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',
      editorRightPanel: [{
        modes: [EditorMode.TRANSLATE, EditorMode.REVIEW],
        supportsMultipleStrings: true,
        uiPath: import.meta.dirname + '/public'
      }],
      editorButton: [
        {
          key: 'open-panel',
          name: 'Open Sample App',
          location: EditorButtonLocations.HEADER_RIGHT,
          type: EditorButtonTypes.PANEL,
          modes: [EditorMode.TRANSLATE, EditorMode.REVIEW]
        },
        {
          key: 'check-strings',
          name: 'Check selected strings',
          location: EditorButtonLocations.STRINGS_MENU,
          type: EditorButtonTypes.EVENT,
          modes: [EditorMode.TRANSLATE, EditorMode.REVIEW]
        }
      ]
    };

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

| Option | Required | Description |
|--------|----------|-------------|
| `location` | yes | Where the button appears: `header-right` or `header-left` (the Editor header), `menu` (the Editor's Apps menu), `translation-toolbar`, or `strings-menu` (the strings context menu) |
| `type` | yes | What a click does: `panel` opens an `editorRightPanel` module, `modal` opens a `modal` module, `event` sends `editor.button.click` to an `editorRightPanel` module. `event` is available at `translation-toolbar` and `strings-menu` only |
| `modes` | yes | The Editor modes the button is shown in |
| `moduleKey` | no | Key of the target module. Leave it out when the app declares a single module of the target type |
| `name` | no | Button label and tooltip. Defaults to the app name |
| `weight` | no | Non-negative integer that orders the buttons at one location; lower weights come first (default `100`) |
| `imagePath` / `imageUrl` | no | Button icon. Defaults to the app logo |
| `environments` | no | `crowdin`, `crowdin-enterprise`, or both |
| `key` | no | Button key. It must differ from the keys of the app's right panels and modals |

`createApp` throws at startup when a button's target can't be resolved: `moduleKey` names no module of the target type, the app declares no such module, or it declares several and `moduleKey` is missing. The Editor hides a button wherever its target is unavailable, for example in a mode the target panel's `modes` leave out.

## Handling clicks

A button of the `event` type doesn't open anything. Its target panel receives the click through the [Crowdin Apps JS](https://support.crowdin.com/developer/crowdin-apps-js/) events:

```js
AP.events.on('editor.button.click', (click) => {
  if (click.location === 'strings-menu') {
    console.log(click.key, click.stringIds, click.languageIds);
  } else {
    console.log(click.key, click.stringId, click.pluralId, click.languageIds);
  }
});
```

A `translation-toolbar` button sends the string being translated (`stringId`, `pluralId`), a `strings-menu` button sends the selected strings (`stringIds`). Both carry `languageIds`, which is empty when no target language applies. Set `supportsMultipleStrings: true` on a panel that receives `strings-menu` clicks - without it, the Editor covers the panel while several strings are selected.