# App Preferences

Source: https://docs.interop.io/browser/capabilities/app-preferences/index.html

## Overview

Available since io.Connect Browser 3.2

The App Preferences API enables apps to store custom user-specific data and retrieve it when necessary. This allows you to enhance the UX of your apps by instrumenting them to preserve specific user settings and apply them when the app is relaunched.

The App Preferences API provides methods for updating, replacing and clearing user settings stored for the current or a specific app, as well as for all apps of the current user.

The App Preferences API is accessible via the [`io.prefs`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md) object.

## Configuration

To provide settings for the App Preferences API, use the `applicationPreferences` top-level key in the configuration object for initializing the [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) library.

The `applicationPreferences` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `store` | `object` | Settings for the app preferences store. |
| `validNonExistentApps` | `string[]` \| `"all"` | Controls the validation behavior when saving app preferences. By default, preferences can be saved only for apps that exist in the app store. Provide an array of app names to allow saving preferences for specific non-existent apps, or set to `"all"` to disable validation entirely, allowing preferences to be saved for any app name. *Available since **io.Connect Browser** 3.5.* |

Available since io.Connect Browser 4.3

The `validNonExistentApps` property accepts also `"all"` as a value, which disables app validation entirely, allowing preferences to be saved for any app name:

```javascript
const config = {
    licenseKey: "my-license-key",
    applicationPreferences: {
        validNonExistentApps: "all"
    }
};

const { io } = await IOBrowserPlatform(config);
```

## App Preferences Stores

App preferences can be stored locally or remotely by using a REST service or [**io.Manager**](https://docs.interop.io/manager/overview/index.md).

To provide settings for app preferences stores, use the `store` property of the `applicationPreferences` top-level key in the configuration object for initializing the [`@interopio/browser-platform`](https://www.npmjs.com/package/@interopio/browser-platform) library.

The `store` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `rest` | `object` | Settings for a REST app preferences store. Valid only in `"rest"` mode. *Available since **io.Connect Browser** 4.0.* |
| `type` | `"local"` \| `"rest"` \| `"manager"` | The type of the app preferences store. Set to `"local"` to store and read app preferences locally using the browser `IndexedDB` API. Set to `"rest"` to store and fetch app preferences from a remote REST service. Set to `"manager"` to store and fetch app preferences from [**io.Manager**](https://docs.interop.io/manager/overview/index.md). |

### Local

By default, app preferences are stored locally using the `IndexedDB` API of the browser.

To instruct **io.Connect Browser** to manage app preferences using a local app preferences store, set the `type` property of the `store` object to `"local"`.

The following example demonstrates how to configure the platform to use the browser `IndexedDB` API to store app preferences locally:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    applicationPreferences: {
        store: {
            type: "local"
        }
    }
};

const { io } = await IOBrowserPlatform(config);
```

### REST

App preferences can also be obtained from remote Layout stores via a REST service.

> ℹ️ *For a reference implementation of a remote app preferences store, see the [Node.js REST Config](https://github.com/InteropIO/rest-config-example-node-js) example.*

To instruct **io.Connect Browser** to manage app preferences using a remote REST service, set the `type` property of the `store` object to `"rest"` and provide settings for the REST store by using the `rest` object.

The `rest` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `cache` | `object` | Settings for caching the app definitions. *Available since **io.Connect Browser** 4.1.* |
| `customHeaders` | `object` | Object containing key/value pairs of headers that will be appended to every request to the remote store. |
| `getRequestInit` | `function` | Function that must return a [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit) object. This object will be merged with the default one and will be appended to every request sent to the remote store. Use this to provide custom request options or to override the default ones. *Available since **io.Connect Browser** 3.5.* |
| `pollingInterval` | `number` | Interval in milliseconds at which to poll the remote store for updates. If not provided, the platform will fetch the Layout definitions only once on startup. Defaults to `0`. |
| `requestTimeout` | `number` | Interval in milliseconds to wait for a response to the request for fetching Layout definitions from the remote store. Defaults to `30000`. |
| `url` | `string` | **Required.** URL pointing to the remote store. |
| `waitInitialResponse` | `boolean` | If `true` (default), the platform will wait for an initial response before proceeding with the platform initialization. In case of an error or no response within the specified request timeout, the platform won't initialize. *Available since **io.Connect Browser** 4.1.* |

The `cache` object has the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `enabled` | `boolean` | If `true`, the retrieved app preferences will be cached by using the browser `IndexedDB` API and the cached app preferences will be returned as a response to any API calls. If caching is enabled, you must also set the `pollingInterval` property to instruct the platform at what interval to retrieve app preferences from the remote store. Defaults to `false`. |

The following example demonstrates how to configure the platform to use a remote REST service as an app preferences store:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    applicationPreferences: {
        store: {
            type: "rest",
            // Settings for the REST store.
            rest: {
                url: "https://my-remote-store/app-preferences"
            }
        }
    }
};

const { io } = await IOBrowserPlatform(config);
```

The remote store must return an [`AppPreferences`](https://docs.interop.io/browser/reference/javascript/app%20preferences/apppreferences/index.md) object as a response.

### io.Manager

You can also use [**io.Manager**](https://docs.interop.io/manager/overview/index.md) for hosting and retrieving app preferences.

The following example demonstrates how to configure the platform to use **io.Manager** as an app preferences store:

```javascript
import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    applicationPreferences: {
        store: {
            type: "manager"
        }
    }
};

const { io } = await IOBrowserPlatform(config);
```

> ℹ️ *For more details on how to configure **io.Connect Browser** to connect to **io.Manager**, see the [io.Manager](https://docs.interop.io/browser/capabilities/manager/index.md) section.*

## Get

To retrieve the stored app preferences for the current app, use the [`get()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-get) method:

```javascript
const prefs = await io.prefs.get();
```

This method resolves with an [`AppPreferences`](https://docs.interop.io/browser/reference/javascript/app%20preferences/apppreferences/index.md) object with the following properties:

| Property | Type | Description |
|----------|------|-------------|
| `app` | `string` | The name of the app with which are associated the stored preferences. |
| `data` | `object` | The stored app preferences. |
| `lastUpdate` | `string` | Timestamp of the last update of the app preferences. |

To retrieve the stored app preferences for a specific app, pass an app name to the [`get()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-get) method:

```javascript
const appName = "clientlist";
const prefs = await io.prefs.get(appName));
```

To retrieve the stored app preferences for all apps of the current user, use the [`getAll()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-get) method:

```javascript
const prefs = await io.prefs.getAll();

// The returned object has an `all` property which contains a list of `AppPreferences` objects.
prefs.all.forEach(console.log);
```

## Set

To set the preferences for the current app, use the [`set()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-set) method:

```javascript
const prefs = { fontSize: 18 };

await io.prefs.set(prefs);
```

The `set()` method replaces entirely the stored app preferences. All existing properties of the `AppPreferences` object associated with the app will be removed and replaced with the ones of the argument provided to the `set()` method.

To set the preferences for a specific app, pass an options object as a second argument to the [`set()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-set) method and specify the name of the app:

```javascript
const prefs = { fontSize: 18 };
const options = { app: "clientlist" };

await io.prefs.set(prefs, options);
```

## Update

To update the preferences for the current app, use the [`udpate()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-update) method:

```javascript
const prefs = { fontSize: 18 };

await io.prefs.update(prefs);
```

The `update()` method modifies only the properties provided in the update object. All other existing properties of the `AppPreferences` object associated with the app will remain intact.

To update the preferences for a specific app, pass an options object as a second argument to the [`update()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-update) method and specify the name of the app:

```javascript
const prefs = { fontSize: 18 };
const options = { app: "clientlist" };

await io.prefs.update(prefs, options);
```

## Clear

To remove the stored app preferences for the current app, use the [`clear()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-clear) method:

```javascript
await io.prefs.clear();
```

To remove the stored app preferences for a specific app, pass an app name to the [`clear()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-clear) method:

```javascript
const appName = "clientlist";

await io.prefs.clear(appName);
```

To remove the stored app preferences for all apps of the current user, use the [`clearAll()`](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md#API-clearAll) method:

```javascript
await io.prefs.clearAll();
```

## API Reference

For a complete list of the available App Preferences API methods and properties, see the [App Preferences API Reference Documentation](https://docs.interop.io/browser/reference/javascript/app%20preferences/api/index.md).
