---
metadata:
  - name: generator
    content: Diplodoc Platform v5.66.1
  - property: og:type
    content: article
  - property: article:section
    content: Plugin platform
  - property: og:title
    content: How the plugin platform works
  - property: article:tag
    content: Technical instructions
alternate:
  - https://yandex.ru/support/tracker/en/plugins/common.md
  - https://yandex.ru/support/tracker/ru/plugins/common.md
  - href: https://yandex.ru/support/tracker/en/plugins/common.md
    type: text/markdown
    title: Markdown version
  - href: https://yandex.ru/support/tracker/en/llms.txt?revision=r22057024
    rel: describedby
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.ru/support/tracker/en/llms.txt?revision=r22057024


# How the plugin platform works

A plugin is a standalone frontend JavaScript application that runs in an iframe inside the Tracker app. An SDK is provided for its development. Using React is considered a priority. There is also a vanilla JavaScript library that allows you to avoid being tied to React.

The platform covers the entire lifecycle of plugins: it provides tools for development and debugging, versioning, and publishing, as well as a repository for storing plugins. Administrators can install, update, and disable plugins, controlling their availability to users and contexts.

## Running a plugin in an iframe {#iframe}

The interface part of plugins is static content hosted on Tracker's servers. It runs in an isolated iframe on a cookieless domain, where almost everything is forbidden, including network requests. Therefore, communication with Yandex services, the Tracker public API, and the outside world is done through the SDK. The exception is [direct requests](https://yandex.ru/support/tracker/en/plugins/externalApi.md#direct-access) to external domains explicitly allowed in the manifest.

## SDK {#sdk}

Interacting with Tracker is done using the [SDK](https://yandex.ru/support/tracker/en/plugins/tools/index.md#sdk), which is connected as a library. The SDK provides methods for interaction at the user interface level, [methods for working with the Tracker public API](https://yandex.ru/support/tracker/en/plugins/trackerApi.md), and a [plugin data storage](https://yandex.ru/support/tracker/en/plugins/storage.md).

The SDK is delivered as two npm packages:

- [**core**](https://yandex.ru/support/tracker/en/plugins/tools/sdk/core.md) — API client and basic integration primitives (JS/TS).
- [**react**](https://yandex.ru/support/tracker/en/plugins/tools/sdk/react.md) — React wrappers over core for easy UI development.

## CLI {#cli}

[CLI](https://yandex.ru/support/tracker/en/plugins/tools/cli.md) is a command-line utility in the form of an NPM package that covers the entire plugin lifecycle: creation, debugging, validation, and publishing.

## UI components {#ui-components}

A [library of UI components](https://yandex.ru/support/tracker/en/plugins/components/index.md) in Tracker's style, available for use in plugins.

## Manifest {#manifest}

The manifest is a `manifest.json` file in the project's root directory. It describes the plugin, the requested permissions, and integration points with Tracker.

### JSON Schema {#manifest-schema}

When creating a project, CLI adds a `manifest.schema.json` file next to the manifest and specifies it in the `$schema` field:

```json
{
  "$schema": "./manifest.schema.json"
}
```

The code editor uses the schema to validate the manifest, provide autocomplete, and show allowed values. CLI validates the manifest against the built-in schema even if the `$schema` field is missing. Do not edit `manifest.schema.json` manually. To update the local schema and other template files, run `weavix up`.

Restrictions and lists of allowed values may change. Check them in the `manifest.schema.json` of the current project.

### Manifest fields {#manifest-fields}

#|
|| **Field** | **Type** | **Required** | **Description** ||
|| `$schema` | `string` | No | Path to the JSON Schema. CLI adds the value `./manifest.schema.json` ||
|| `manifest_version` | `number` | No | Manifest format version. CLI adds the value `1` ||
|| `supported_services` | `string[]` | No | Services where the plugin works. For a Tracker plugin, specify `["tracker"]` ||
|| `slug` | `string` | Yes | Unique plugin name consisting of lowercase Latin letters, numbers, and hyphens. Length: 3 to 63 characters ||
|| `id` | `string` | No | Plugin ID on the platform. CLI adds it during registration when you first run the `submit` command. Do not set this field manually ||
|| `version` | `string` | Yes | Plugin version in SemVer format, for example, `1.2.0` ||
|| `name` | `object` | Yes | Name in Russian and English in the `ru` and `en` fields. Length of each value: 1 to 30 characters ||
|| `description` | `object` | Yes | Description in Russian and English in the `ru` and `en` fields. Length of each value: 1 to 255 characters ||
|| `support` | `object[]` | Yes | Non-empty list of support contacts. Each object contains `type` with the value `email` and an address of up to 100 characters in the `value` field ||
|| `permissions` | `object` | Yes | [Permissions](#permissions) required by the plugin. The object must contain the `data` field ||
|| `slots` | `object` | No | [Integration points](https://yandex.ru/support/tracker/en/plugins/slots/index.md) of the plugin with the services interface ||
|| `categories` | `string[]` | No | [Categories](https://yandex.ru/support/tracker/en/plugins/publish.md#category) by which the plugin is displayed in the catalog ||
|| `docsUrl` | `string` | No | Address of the [plugin help](https://yandex.ru/support/tracker/en/plugins/publish.md#docs) ||
|| `homepage` | `string` | No | Plugin website address with the HTTP or HTTPS protocol ||
|| `license` | `string` | No | License identifier up to 32 characters, for example, `MIT` or `Apache-2.0` ||
|| `keywords` | `string[]` | No | Unique keywords for searching the plugin. Length of each value: up to 30 characters ||
|| `whatsnew` | `string` | No | Description of changes in the version, up to 300 characters ||
|| `externalHost` | `string` | No | HTTPS address from which the plugin interface is loaded. Using an external host requires approval from the Tracker team ||
|#

### Configuring slots {#manifest-slots}

A plugin can use multiple integration points. For each point, specify:

- `entrypoint` — path to the entry HTML file;
- `title` — interface element name in Russian and English;
- `contextLevel` — level of data available to the plugin:
    - `basic` — ID of the current entity and basic metadata;
    - `full` — full entity object, for example, all issue fields;
- `description` — optional description in Russian and English;
- `icon` — optional object with a path to the icon in the `url` field. Used in the `dock` slot.

Use `full` only if the plugin needs the full entity object.

The `slots` field is not required by the manifest format, but you must configure at least one slot to validate and publish the project.

```json
"slots": {
  "tracker": {
    "issue.action": [
      {
        "entrypoint": "index.html",
        "contextLevel": "basic",
        "title": {
          "ru": "Мой плагин",
          "en": "My Plugin"
        }
      }
    ]
  }
}
```

## Permissions {#permissions}

In the manifest, specify only the permissions that the plugin needs. The `permissions` object contains the following fields:

- `data` — required array of permissions for working with Tracker data. Permissions have the format `tracker:<resource>:read` for reading and `tracker:<resource>:write` for modifying data. For example, `tracker:issues:read` allows reading issues, `tracker:issues:write` allows modifying them, and `tracker:attachments:write` allows uploading attachments. The current list of allowed values is provided in `manifest.schema.json`;
- `device` — access to the user's device capabilities. Allowed values: `clipboard-write`, `microphone`, `camera`, `geolocation`, `web-share`, and `allow-downloads`. If supported by the browser, the user must additionally allow access to the selected capability;
- `ui` — additional actions in the Tracker interface. Add such a permission only if it's specified in the description of the SDK method you're using;
- `external` — domains of external APIs, the access method for them (`access`), and authorization parameters. The primary method is requests through the platform proxy (`proxy`). Direct requests from the browser (`direct`) don't support authorization and aren't recommended. For more information, see [External APIs](https://yandex.ru/support/tracker/en/plugins/externalApi.md#manifest).

{% note warning "Access level" %}

A permission in the manifest does not extend the user's rights. All actions are performed on behalf of the current user and within the rights granted to them.

{% endnote %}

## Plugin data storage {#plugin-data-storage}

The platform provides the plugin with its own JSON storage, `storageApi`. Data is stored on the platform side, so it does not depend on the user's device. The record's visibility scope is determined by its context:

- **`orgShared`**: A shared record for the entire organization. This is suitable for common plugin settings and reference data caches.
- **`user`**: A personal record of the current user. This is suitable for personal settings and UI state.
- **`resource`**: A record linked to a Tracker resource by the `resourceId` identifier, such as `issue:MYQUEUE-123` or `queue:MYQUEUE`. The record is shared by all users who access this resource.

Within a context, the plugin can store multiple independent records separated by the `bucket` key. The `get` operation reads a record, and `patch` creates or modifies it using merge semantics: a `null` value deletes the field. Concurrent changes are controlled by the record version (optimistic locking).

For more information about the current storage implementation and its API, see the [Plugin data storage](https://yandex.ru/support/tracker/en/plugins/storage.md) section.

## Access to external APIs via proxy {#external-api-access}

The platform provides a secure mechanism for integrations with external services: a platform proxy for making HTTP requests and authorization of these requests with the user's personal token.

- **Platform proxy** — a single endpoint for calling external APIs on behalf of the plugin. The plugin sends the request parameters: URL, method, headers, body. The platform executes the request on the backend and returns the result. Access is restricted declaratively (domain allowlist). The platform blocks unsafe destinations (private networks/localhost, unauthorized redirects), runs audits, and applies rate limits per `pluginId` and organization.

- **Proxy request authorization** — the plugin author specifies in the manifest which token a domain requires and which header to put it in. The token itself is not specified in the manifest. If there is no token yet, Tracker shows the user a token entry dialog with the plugin author's instructions. The token is stored on the platform side and is never passed to the plugin's iframe: the plugin only learns whether authorization exists. When making requests through the proxy, the platform inserts the token automatically. Only the user's personal tokens are supported — the **`user`** context.

For more information on how to call external APIs from a plugin, see the [External APIs](https://yandex.ru/support/tracker/en/plugins/externalApi.md) section.

A plugin can also send [direct requests](https://yandex.ru/support/tracker/en/plugins/externalApi.md#direct-access) to external APIs from the browser. The platform isn't involved in such requests: they don't support authorization, audits, or proxy protection, so they aren't recommended.

## Integration points (slots) {#integration-points}

The location where the plugin will be opened, as well as the mechanism for invoking it (such as a button or as part of a form), is determined by the slot. The slot is specified in the manifest.

Available slots and details of their use are described in the [Integration points](https://yandex.ru/support/tracker/en/plugins/slots/index.md) section.

## Plugin launch context {#launch-context}

The plugin launch context is determined by the slot it is in and contains the following information:

- Current Tracker theme
- Current Tracker language
- Slot context — data from the environment of the page where the plugin is running. For example, in the `issue.action` slot, information about the open issue will be returned. The context format is as close to the public API types as possible.

### Slot context levels {#context-levels}

The context level is set by the `contextLevel` parameter in the slot description in `manifest.json` and determines what data will be available to the plugin via [`useTrackerPluginContext`](https://yandex.ru/support/tracker/en/plugins/tools/sdk/react.md#use-tracker-plugin-context).

#### basic {#basic}

Only the current entity ID and basic metadata are available:

```typescript
type BasicContext = {
    /** Current entity ID */
    entityId: string;
    /** Additional basic information about the entity.
     *  For example, for a comment, this will contain the parent issue ID. */
    entityMeta?: Record<string, string>;
};
```

Use `basic` if the plugin only needs to know the entity ID — this is a lighter option without unnecessary overhead.

#### full {#full}

Full context with live entity data. The format matches the public API types. For example, for the `issue.action` slot, it's the full `Issue` object. The data is up to date as of the moment the plugin is opened.

Use `full` only if the plugin really needs the full entity data.

{% note warning "Choosing a context level" %}

Request only the context level that the plugin actually needs. If you don't need full entity data, use `basic`.

{% endnote %}