# JavaScript

Source: https://docs.interop.io/desktop/getting-started/how-to/interop-enable-your-apps/javascript/index.html

## Using the JavaScript Library

The [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) library provides APIs with which you can access the io.Connect functionalities and interop-enable your web apps. You can either [auto inject](#auto_injection) (and optionally auto initialize) the library in your apps, or reference it (either as an [NPM module](#referencing-from_an_npm_module), or as a [standalone JavaScript file](#referencing-from_a_javascript_file)) and then [initialize](#initialization) it. Both approaches have their respective advantages and disadvantages. Usually, it's recommended to choose a global approach for all your interop-enabled apps (in some cases, there may be hundreds of interop-enabled apps in use) based on what best suits your needs and requirements.

Auto injecting the library is preferable if you want all your interop-enabled apps to use the same version of the library and have the option to be easily updated to the latest version of `@interopio/desktop`. Updating the library in all apps can be accomplished simply by redeploying **io.Connect Desktop** - all interop-enabled apps will be automatically injected with the new version of the library, saving you the effort to update them one by one. Another option is to use a REST service providing the latest library versions. When using auto injection, however, your apps won't be interop-enabled if running in a browser, which is something to consider if you want to use them in a browser. Auto injection may not work well for you in some other cases as well, depending on your production and deployment model.

Using the `@interopio/desktop` library as a standalone file or as an NPM package has its advantages too - your apps can use a different version of the library if necessary. Also, your apps can be interop-enabled in a browser. This, of course, means that updating the library can be a tedious and slow process, especially if you have many interop-enabled apps, the majority of which are using different versions of the library.

## Referencing

The [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) library is available as an NPM package which you can include as a dependency in your project and import in your code.

> ⚠️ *Note that the `@interopio/desktop` depends on the [`@interopio/core`](https://www.npmjs.com/package/@interopio/core) library. The `@interopio/core` library is a subset of `@interopio/desktop` and offers only basic functionalities for sharing data between apps ([Interop](https://docs.interop.io/desktop/capabilities/data-sharing/interop/overview/index.md), [Shared Contexts](https://docs.interop.io/desktop/capabilities/data-sharing/shared-contexts/overview/index.md), [Pub/Sub](https://docs.interop.io/desktop/capabilities/data-sharing/pub-sub/overview/index.md)), while the `@interopio/desktop` library offers additional, more sophisticated interoperability options such as ([Channels](https://docs.interop.io/desktop/capabilities/data-sharing/channels/overview/index.md), [Intents](https://docs.interop.io/desktop/capabilities/data-sharing/intents/overview/index.md)), as well as advanced app and window management functionalities ([App Management](https://docs.interop.io/desktop/capabilities/app-management/overview/index.md), [Layouts](https://docs.interop.io/desktop/capabilities/windows/layouts/overview/index.md), [Window Management](https://docs.interop.io/desktop/capabilities/windows/window-management/overview/index.md)). The `@interopio/desktop` library also provides APIs for using [Notifications](https://docs.interop.io/desktop/capabilities/notifications/overview/index.md), [App Preferences](https://docs.interop.io/desktop/capabilities/app-preferences/overview/index.md), [Themes](https://docs.interop.io/desktop/capabilities/windows/themes/overview/index.md), [Displays](https://docs.interop.io/desktop/capabilities/more/apis/index.md#displays), [Hotkeys](https://docs.interop.io/desktop/capabilities/more/apis/index.md#hotkeys), [Interception](https://docs.interop.io/desktop/capabilities/interception/overview/index.md), and more.*

To install the `@interopio/desktop` library, execute the following command:

```cmd
npm install @interopio/desktop
```

You can now import the factory function exposed by the library and start interop-enabling your apps:

```javascript
import IODesktop from "@interopio/desktop";
```

You can also reference the library as a JavaScript file in the HTML file of your web app using a `<script>` tag:

```html
<script type="module" src="./desktop.umd.js"></script>
```

When deploying your app in production, it's recommended to always reference a specific minified version:

```html
<script type="module" src="./desktop.umd.min.js"></script>
```

## Initialization

The following sections describe how to initialize the [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) library depending on whether your web app will run in an [io.Connect Window](https://docs.interop.io/desktop/capabilities/windows/window-management/overview/index.md) or in a web browser.

### io.Connect Window

The [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) library exposes a global factory function called `IODesktop()`. It accepts as an argument an optional [`Config`](https://docs.interop.io/desktop/reference/javascript/io.connect%20desktop/config/index.md) object which you can use to configure various library features. To initialize the library, invoke the factory function and use the returned API object to access the io.Connect APIs:

```javascript
import IODesktop from "@interopio/desktop";

// It isn't necessary to specify any configuration.
const io = await IODesktop();

// Now you can use the io.Connect APIs via the initialized API object.
await io.appManager.application("my-app").start();
```

The optional [`Config`](https://docs.interop.io/desktop/reference/javascript/io.connect%20desktop/config/index.md) object allows you to configure some of the available io.Connect APIs. You can enable or disable an API and for some of the APIs it's possible to specify the level of features your app will require from them. For more details on configuring the different APIs, see the respective entry in the [Capabilities](https://docs.interop.io/desktop/capabilities/launcher/index.md) section.

### Web Browser

If you want to run your app in a web browser, you must provide the necessary details and authentication information for connecting to the io.Connect framework as demonstrated in the following example:

```html
<script type="module" src="desktop.umd.min.js"></script>

<script>
    const initializeIOConnect = async () => {
        const config = {
            // Name for your app.
            application: "MyWebApp",
            // Settings for connecting to the io.Connect Gateway.
            gateway: {
                protocolVersion: 3,
                ws: "<gateway_url>"
            },
            // Authentication settings.
            auth: {
                username: "<username>",
                password: "<password>"
            }
        };

        window.io = await IODesktop(config);
    };

    initializeIOConnect().catch(console.error);
</script>
```

## Auto Injection

Auto injection can be configured on system level and can be overridden on an app level (with some limitations). You can also optionally specify whether you want to auto initialize the library after injection.

### System Level

To enable auto injection on system level, use the `"autoInjectAPI"` property under the `"windows"` top-level key in the `system.json` [system configuration](https://docs.interop.io/desktop/developers/configuration/system/index.md) file of **io.Connect Desktop**:

```json
{
    "windows": {
        "autoInjectAPI": {
            "enabled": true,
            "version": "5.11.2",
            "autoInit": false
        }
    }
}
```

The `"autoInjectAPI"` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"allowed"` | `string[]` | List of io.Connect app names in which the [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) library will be injected. Defaults to `[]`. |
| `"autoInit"` | `boolean` \| `object` | Setting for auto initializing the `@interopio/desktop` library. Accepts either a `boolean` value, or a [`Config`](https://docs.interop.io/desktop/reference/javascript/io.connect%20desktop/config/index.md) object with which to initialize the library. |
| `"blocked"` | `string[]` | List of io.Connect app names in which the `@interopio/desktop` library won't be injected. Defaults to `[]`. |
| `"enabled"` | `boolean` | **Required**. If `true`, will enable auto injecting the `@interopio/desktop` library. Defaults to `false`. |
| `"version"` | `string` | **Required**. Semantic version of the library to inject. It's recommended to use a specific version and avoid wildcard versions. Defaults to `"*"`. |

Each version of **io.Connect Desktop** is distributed with a set of `@interopio/desktop` library version that are used for auto injection. You can see the versions available for auto injection in the `<installation_location>/interop.io/io.Connect Desktop/Desktop/assets/preloads` folder. If you specify a version which isn't available, **io.Connect Desktop** will continue working normally without injecting a library in the apps running in it.

If the library is injected but not auto initialized, you can use the `IODesktop()` factory function to initialize it and pass an optional [`Config`](https://docs.interop.io/desktop/reference/javascript/io.connect%20desktop/config/index.md) object to it:

```javascript
// Enabling the Channels API.
const config = { channels: true };

const io = await IODesktop(config);

console.log(`io.Connect JS version ${io.version} has been successfully initialized!`);
console.log(`Channels are ${io.channels ? "enabled" : "disabled"}.`);
```

If the library is injected and auto initialized, you should use the injected `ioPromise` in the `window` object to wait for the io.Connect API:

```javascript
await ioPromise.catch(console.error);

// The returned `io` object is assigned to the global `window` object.
if (window.io) {
    console.log(`io.Connect JS version ${io.version} has been successfully initialized!`);

    // Channels are disabled by default. If you haven't specified a custom initialization object that enables
    // the Channels API in the `autoInit` property under `autoInjectAPI` (e.g., "autoInit": { "channels": true }),
    // then the following check will return `false`.
    console.log(`Channels are ${io.channels ? "enabled" : "disabled"}.`);
}
```

#### Filtering

You can allow and block apps on system level to control which apps should be auto injected with the library and which should use their own version of the library instead.

- all allowed apps will be auto injected with the library, all other apps won't be auto injected:

```json
{
    "windows": {
        "autoInjectAPI": {
            "enabled": true,
            "version": "5.9.0",
            "autoInit": false,
            "allowed": ["my-app", "my-other-app"]
        }
    }
}
```

- blocked apps won't be auto injected with the library, all other apps will be auto injected:

```json
{
    "windows": {
        "autoInjectAPI": {
            "enabled": true,
            "version": "5.9.0",
            "autoInit": false,
            "blocked": ["my-app", "my-other-app"]
        }
    }
}
```

If an app is both in the allowed and the blocked lists, it will be auto injected with the library.

### App Level

If auto injection of the library is disabled on system level, it can't be enabled on an app level. If auto injection is enabled on system level, then each app can opt out of it. Apps can specify whether the auto injected library will be auto initialized or not, but can't specify which version of the library to be auto injected - this is possible only on system level. If an app needs to use a different version of the library than the auto injected one, you should disable auto injection in the app definition and reference a version of the library file in your app instead.

To configure auto injection on an app level, use the `"autoInjectAPI"` property of the `"details"` top-level key in the [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md).

> ℹ️ *For more details on how to create an app definition and where the app definition files should be stored, see the [App Definition](#app_definition) section or the [Developers > Configuration > Application](https://docs.interop.io/desktop/developers/configuration/application/index.md#app_definition) section.*

The following is an example configuration for auto injection on an app level:

```json
{
    "details": {
        "autoInjectAPI": {
            "enabled": true,
            "autoInit": false
        }
    }
}
```

The `"autoInjectAPI"` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `"autoInit"` | `boolean` \| `object` | If `true`, will initialize the injected library. Accepts either a `boolean` value, or a [`Config`](https://docs.interop.io/desktop/reference/javascript/io.connect%20desktop/config/index.md) object with which to initialize the library. |
| `"enabled"` | `boolean` | **Required**. If `true`, will enable auto injecting the library. |

### Auto Initialization

Auto initialization of the injected library can be specified globally in the `system.json` file, or can be overridden on an app level in the app definition file. To enable or disable auto initialization of the library, use the `"autoInit"` property of the `"autoInjectAPI"` object.

If you want to auto initialize your app with custom library configuration, provide a [`Config`](https://docs.interop.io/desktop/reference/javascript/io.connect%20desktop/config/index.md) object with initialization settings instead of a Boolean value.

The following example demonstrates how to auto initialize an app and enable [Channels](https://docs.interop.io/desktop/capabilities/data-sharing/channels/javascript/index.md):

```json
{
    "autoInjectAPI": {
        "enabled": true,
        "autoInit": {
            "channels": true
        }
    }
}
```

> ⚠️ *Note that the auto initialization configuration takes precedence over initializing the library inside your app. The [`@interopio/desktop`](https://www.npmjs.com/package/@interopio/desktop) library can't be initialized more than once - the factory function will always return the first initialized instance, even if you attempt to initialize the library again.*

## App Definition

To add your JavaScript app to the [io.Connect launcher](https://docs.interop.io/desktop/capabilities/launcher/index.md), you must create a JSON [app definition](https://docs.interop.io/desktop/developers/configuration/application/index.md) file for it. Place this file in the `<installation_location>/interop.io/io.Connect Desktop/UserData/<ENV>-<REG>/apps` folder where `<ENV>-<REG>` represents the environment and region of **io.Connect Desktop** (e.g., `DEMO-INTEROP.IO`).

The following is an example definition of a JavaScript app:

```json
{
    "name": "my-app",
    "title": "My App",
    "type": "window",
    "details": {
        "url": "https://example.com/my-app/",
        "mode": "tab",
        "width": 500,
        "height": 400
    }
}
```

The `"name"`, `"type"`, and `"url"` properties are required and `"type"` must be set to `"window"`. The `"url"` property points to the location of the web app.

The value of the `"title"` property will be used as a name for the app in the io.Connect launcher and as a window title if the web app doesn't have a document title.

> ℹ️ *For more details on defining apps, see the [Developers > Configuration > Application](https://docs.interop.io/desktop/developers/configuration/application/index.md) section.*

> ℹ️ *See the [JavaScript examples](https://github.com/InteropIO/js-examples) on GitHub which demonstrate various **io.Connect Desktop** features.*

## io.Connect JavaScript Capabilities

Once the `@interopio/desktop` library has been initialized, your app has access to all io.Connect functionalities. For more detailed information on the different io.Connect capabilities and APIs, see the following sections:

- [Shared Contexts](https://docs.interop.io/desktop/capabilities/data-sharing/shared-contexts/javascript/index.md)
- [Channels](https://docs.interop.io/desktop/capabilities/data-sharing/channels/javascript/index.md)
- [Interop](https://docs.interop.io/desktop/capabilities/data-sharing/interop/javascript/index.md)
- [Intents](https://docs.interop.io/desktop/capabilities/data-sharing/intents/javascript/index.md)
- [Pub/Sub](https://docs.interop.io/desktop/capabilities/data-sharing/pub-sub/javascript/index.md)
- [Window Management](https://docs.interop.io/desktop/capabilities/windows/window-management/javascript/index.md)
- [Workspaces](https://docs.interop.io/desktop/capabilities/windows/workspaces/javascript/index.md)
- [Layouts](https://docs.interop.io/desktop/capabilities/windows/layouts/javascript/index.md)
- [Themes](https://docs.interop.io/desktop/capabilities/windows/themes/javascript/index.md)
- [Modals](https://docs.interop.io/desktop/capabilities/windows/modals/javascript/index.md)
- [App Management](https://docs.interop.io/desktop/capabilities/app-management/javascript/index.md)
- [App Preferences](https://docs.interop.io/desktop/capabilities/app-preferences/javascript/index.md)
- [Notifications](https://docs.interop.io/desktop/capabilities/notifications/javascript/index.md)
- [Search](https://docs.interop.io/desktop/capabilities/search/javascript/index.md)
- [Interception](https://docs.interop.io/desktop/capabilities/interception/javascript/index.md)
- [Hotkeys](https://docs.interop.io/desktop/capabilities/more/apis/index.md#hotkeys)
- [Displays](https://docs.interop.io/desktop/capabilities/more/apis/index.md#displays)
- [Logging](https://docs.interop.io/desktop/capabilities/logging/javascript/index.md)

## API Reference

For a complete list of the available JavaScript APIs, see the [io.Connect JavaScript reference documentation](https://docs.interop.io/desktop/reference/javascript/io.connect%20desktop/index.md).

## Changelog

For all changes in the io.Connect JavaScript libraries, see the [Changelog > Libraries > @interopio/desktop](https://docs.interop.io/desktop/getting-started/changelog/libraries/interopio-desktop/index.md) and [Changelog > Libraries > @interopio/core](https://docs.interop.io/desktop/getting-started/changelog/libraries/interopio-core/index.md) sections.
