> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.noticeable.io/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# How to use the Noticeable JavaScript SDK? 📜

**The _Software Development Kit_ (SDK) enables controlling Noticeable components from your JavaScript code. For instance, it allows rendering Widgets, listening to events, as well as performing actions such as opening, closing, or doing fancy stuff with any Widgets.**

# Loading the Noticeable JavaScript SDK

| The 2-lines code snippet you get for installing a widget already loads the Noticeable SDK. There is no extra actions required to use the SDK.

In the case you need to get the most recent version of the code snippet, you can copy the content from the following URL (it is not recommended to reference this URL directly as a script) :
https://sdk.noticeable.io/s.js

That snippet loads the Noticeable SDK onto the page _asynchronously_, so it won’t affect your page load speed. Once the snippet is running on your site, you can interact with the SDK via the global window variable named `noticeable`.

# Available Commands

You can find the list of supported commands here. Each command may support a set of actions:

* [noticeable.debug()](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#2-debug)
* [noticeable.destroy(...)](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#3-destroy-widget)
* [noticeable.do(...)](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#2-doing-actions)
* [noticeable.identify(...)](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#2-identifying-users)
* [noticeable.is(...)](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#2-checking-states)
* [noticeable.on(...)](https://help.noticeable.io/en-us/article/how-to-listen-to-events-with-the-noticeable-javascript-sdk-m8d6um/#1-listening-to-events)
* [noticeable.off(...)](https://help.noticeable.io/en-us/article/how-to-listen-to-events-with-the-noticeable-javascript-sdk-m8d6um/#1-removing-a-listener)
* [noticeable.ready(...)](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#1-using-span-classcsh-markdown-csh-markdown-code-csh-markdown-code-inline-csh-font-code-regularnoticeablespan-before-it-is-ready)
* [noticeable.render(...)](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#2-rendering-widgets)
* [noticeable.reset(...)](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#2-resetting)
* [noticeable.set(...)](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/#2-setting-values)

|| Note that some commands are asynchronous whereas some are not. Asynchronous commands return a JavaScript promise. You should not use them before the Noticeable SDK is fully loaded, except if you know what you do. For instance, it makes sense to call `render` without waiting for the _ready_ event but checking if a widget is closed with `is('widget:closed', ...)`  requires to synchronize calls, otherwise you will get unexpected results (read about the [Noticeable _ready_ event](https://help.noticeable.io/en-us/article/how-to-use-the-noticeable-javascript-sdk-7k5kc2/?1612522172296#1-using-span-classcsh-markdown-csh-markdown-code-csh-markdown-code-inline-csh-font-code-regularnoticeablespan-before-it-is-ready)).

## Checking States

### Widget Closed

* **Asynchronous**: Yes.
* **Description**: Returns a promise resolving to `true` if the specified widget is closed, `false` otherwise.
* **Code**: `noticeable.is('widget:closed', widgetId);`

### Widget Opened

* **Asynchronous**: Yes.
* **Description**: Returns a promise resolving to `true` if the specified widget is opened, `false` otherwise.
* **Code**: `noticeable.is('widget:opened', widgetId);`

## Debug

The SDK includes an option to show debug traces: `noticeable.debug();`. This synchronous command must appear before all others and should not be used in production.

## Doing Actions

### Close Widget

* **Asynchronous**: No.
* **Description**: Close the widget view. For instance, with the popup widget, the popup is closed but the widget trigger remains visible.
* **Code**: `noticeable.do('widget:close', widgetId);`

### Open Widget

* **Asynchronous**: No.
* **Description**: Open the widget view. For instance, with the popup widget, the popup is opened but the trigger view remains untouched.
* **Code**: `noticeable.do('widget:open', widgetId);`

### Toggle Widget

* **Asynchronous**: No.
* **Description**: Open the widget if it is closed or close the widget if it is opened.
* **Code**: `noticeable.do('widget:toggle', widgetId);`

## Identifying Users

* **Asynchronous**: Yes.
* **Description**: Tie a user to their actions and record traits about them. Returns a promise that fulfills when the command completes.
* **Code**: 

```
noticeable.identify('PROJECT_ID', {
    id: 'a8ONg9xpnGmSg', // your unique user ID
    avatar: 'https://acme.com/john.png', // optional
    name: 'John Doe',  // optional
    email: 'john.doe@acme.com' // optional
});
```
The first parameter to `identify` is your project identifier on Noticeable. The second parameter is an object containing user traits. Traits are pieces of information you know about a user. For now, we allow a limited number of trait fields:

* **id** (required): Unique ID in your database or anonymous ID for a user.
* **avatar** (optional): URL to an avatar image for the user.
* **email** (optional): Email address of a user.
* **name** (optional): User display name.

|| You must call `noticeable.identify(...)` before `noticeable.render('widget', ...)`. The value you pass as user _id_ must be unique and consistent across a user's lifetime. Do not use an email address or a username that can change over time. Besides, [the cross-device synchronization option must be enabled on the dashboard.](/en-us/article/widget-cross-device-synchronization-1m7jpkm/)

## Listening to Events

Open the dedicated article about [how to listen to events with the Noticeable JavaScript SDK](/en-us/article/how-to-listen-to-events-with-the-noticeable-javascript-sdk-m8d6um/).

## Rendering Widgets

### Render Widget

* **Asynchronous**: Yes.
* **Description**: Render the widget with the given identifier. Returns a promise that fulfills when the command completes.
* **Code**: `noticeable.render('widget', widgetId, options);`

The `options` parameter is optional. It's a JavaScript object that allows passing the following options:
* **root**:  An HTML element or shadow root from where the widget selector is searched.
* **segments**: An array of segment values to enable [segmentation](/en-us/article/publication-segmentation-i6wz38/).

* **Example 1**: Render a widget in a web component / custom element:  `noticeable.render('widget', widgetId, {root: this.shadowRoot});`
* **Example 2**: Render a widget with segment values specific to a user seeing the widget:  `noticeable.render('widget', widgetId, {segments: ['Plan:Business', 'Role:Editor']});`

### Destroy Widget

* **Asynchronous**: Yes.
* **Description**: Destroy the widget with the specified identifier. This is the opposite operation of `render(...)`. Nothing happens if the specified widget was not rendered. Returns a promise that fulfills when the command completes.
* **Code**: `noticeable.destroy('widget', widgetId);`


## Resetting

* **Asynchronous**: Yes.
* **Description**: Reset states for the specified project identifier. Unlink any previous identify session. Returns a promise that fulfills when the command completes.
* **Code**: `noticeable.reset(projectId);`

## Setting Values

### Set Global Preferences

* **Asynchronous**: No.
* **Description**: Configure global SDK preferences such as first-party cookies options. 
* **Code**:

```
noticeable.set('preferences', {
  firstPartyCookies: {
    localStorage: false, 
    retentionPeriod: 31536000000
  }
});
```

By default Noticeable uses [local storage for some cookies](/en-us/article/noticeable-widget-cookies-1s0f0ow/). You can disable its usage with the command above. When disabled, legacy cookies with an expiration time are used instead. The default retention period is set to 1 year. You can customize this period as shown above. The value is a number with millisecond precision.

|| Setting global preferences must be done before all other calls to the Noticeable SDK.

### Set Widget Publication Read

* **Asynchronous**: Yes.
* **Description**: Mark the specified publication ID(s) as read. Returns a promise that fulfills when the command completes.
* **Code**: `noticeable.set('widget:publication:read', widgetId, publicationId);`

This command also supports an array of publications as third parameter.

### Set Widget Publication Seen

* **Asynchronous**: Yes.
* **Description**: Mark the specified publication ID(s) as seen. Returns a promise that fulfills when the command completes.
* **Code**: `noticeable.set('widget:publication:seen', widgetId, publicationId);`

This command also supports an array of publications as third parameter.


# Using `noticeable` Before It Is Ready

The Noticeable SDK is loaded asynchronously to prevent slowing down your pages. If you need to synchronize commands that return a promise (asynchronous commands), then do it in the Noticeable `ready` callback:

```
noticeable.ready(async function() {
    const widgetId = 'twIQzr4qsf7VbCrqTVHx';
    await noticeable.render('widget', widgetId);
    noticeable.do('widget:open', widgetId);
    console.log('Is widget closed? ', await noticeable.is('widget:closed', widgetId));
});
```