> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/migration-guides/migrating-to-v11/migrating-to-v11-modular-ui.md).

# Migrating to V11 Modular UI

Discover the new Modular UI in WebViewer 11 for enhanced customization and flexibility. Learn how to import only necessary components, customize your UI, and export configurations easily. Upgrade your

## Overview and Philosophy

In WebViewer 11, the default UI has been changed to the new [Modular UI](/web/ui-customization/modular-ui/getting-started.md). This new UI is more flexible and allows for more customization.

The previous UI is still available and can be used by setting the `ui` option to `legacy` in the WebViewer constructor.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewerConstructor(
  {
    path: '/path/to/your/webviewer',
    initialDoc: '/path/to/your/document.pdf',
    ui: 'legacy',
  },
  document.getElementById('viewer')
).then(instance => {

});
```

{% endcode %}
{% endtab %}
{% endtabs %}

With the Modular UI, you can now easily customize your UI by adding and remove components, or alternatively building your own UI from scratch.

One of the main changes in the Modular UI is that you are able to [import](/web/ui-customization/modular-ui/ui-import-and-export.md#import-a-modular-ui) only the necessary components for your UI, instead of loading them all and disabling the ones you don't need.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-b9a458dec40ed03236cfabc33859c0afa30debe3%2F94a8360aa7fb62445e3e680f63d0351d6d25835e-2554x1368.png?alt=media)

This can be done using a JSON config file in which you can define the [Modular Components](/web/ui-customization/modular-ui/ui-import-and-export.md#modular-components) (ie. Buttons, Ribbon Items, Grouped Items), [Modular Headers](/web/ui-customization/modular-ui/ui-import-and-export.md#modular-headers), [Flyouts](/web/ui-customization/modular-ui/ui-import-and-export.md#flyouts), and [Panels](/web/ui-customization/modular-ui/ui-import-and-export.md#panels) that you want to use and then importing it into the UI.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
Webviewer.WebComponent(
  {
    path: '/path/to/your/webviewer',
    initialDoc: '/path/to/your/document.pdf',
  },
  viewerElement
).then((instance) => {
  const configUI = {
    "modularComponents": {
      "myButton": {
        "type": "customButton",
        "dataElement": "myButton",
        "label": "My Button",
        "onClick": "alertClick"
      },
      "flyoutToggle": {
        "type": "toggleButton",
        "img": "ic-hamburger-menu",
        "dataElement": "flyoutToggle",
        "toggleElement": "myFlyout"
      },
      "flyoutFirstButton": {
        "type": "customButton",
        "dataElement": "flyoutFirstButton",
        "label": "Flyout First Button",
        "children": [
          "flyoutSecondButton"
        ]
      },
      "flyoutSecondButton": {
        "type": "customButton",
        "dataElement": "flyoutSecondButton",
        "label": "Flyout Second Button",
        "onClick": "flyoutSecondButtonOnClick"
      },
      "searchPanelToggle": {
        "type": "toggleButton",
        "img": "icon-header-search",
        "dataElement": "searchPanelToggle",
        "toggleElement": "myPanel"
      }
    },
    "modularHeaders": {
      "myHeader": {
        "dataElement": "myHeader",
        "placement": "top",
        "items": [
          "flyoutToggle",
          "myButton",
          "searchPanelToggle"
        ]
      }
    },
    "panels": {
      "myPanel": {
        "dataElement": "myPanel",
        "location": "left",
        "render": "searchPanel"
      }
    },
    "flyouts": {
      "myFlyout": {
        "dataElement": "myFlyout",
        "items": [
          "flyoutFirstButton"
        ]
      }
    }
  };

  const functionMap = {
    'alertClick': () => alert('Alert triggered!'),
    'flyoutSecondButtonOnClick': () => {
      console.log('Second Item clicked!');
    },
  };

  instance.UI.importModularComponents(configUI, functionMap);
});
```

{% endcode %}
{% endtab %}
{% endtabs %}

[UI.importModularComponents](https://sdk.apryse.com/api/web/UI.html#.importModularComponents__anchor)

In the example above, a [functionMap](/web/ui-customization/modular-ui/ui-import-and-export.md#adding-a-function-map) is also used to define the onClick functions for the buttons.

This new way of customizing the WebViewer UI is more flexible and allows for more control over the UI components that are used.

Along with importing UI configs, there is also the new ability to export a UI config using the [UI.exportModularComponents](https://sdk.apryse.com/api/web/UI.html#.exportModularComponents__anchor) API. This can be useful if you want to save a UI configuration to use in another instance of WebViewer.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const exportedUI = instance.UI.exportModularComponents();
console.log(exportedUI);
```

{% endcode %}
{% endtab %}
{% endtabs %}

[UI.exportModularComponents](https://sdk.apryse.com/api/web/UI.html#.exportModularComponents__anchor)

## Modular UI Equivalents for Existing APIs

Because of the change to the new UI, there are now different APIs for interacting with and customizing the WebViewer UI.

The table below summarizes how a few of the existing APIs have changed in the Modular UI:

| Existing API                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Matching API in Modular UI                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [setToolBarGroup()](https://sdk.apryse.com/api/web/UI.html#.setToolbarGroup)                                                                                                                                                                                                                                                                                                                                                                                                                    | <ul><li><a href="https://sdk.apryse.com/api/web/UI.html#.setActiveRibbonItem">setActiveRibbonItem(dataElement)</a></li></ul><p>New Modular API, also has a matching getter to see which ribbon item is currently active, <a href="https://sdk.apryse.com/api/web/UI.html#.getActiveRibbonItem">getActiveRibbonItem()</a></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| [setHeaderItems()](https://sdk.apryse.com/api/web/UI.html#.setToolbarGroup)                                                                                                                                                                                                                                                                                                                                                                                                                     | <ul><li><a href="https://sdk.apryse.com/api/web/UI.html#.getModularHeader">getModularHeader(dataElement)</a> - returns a header with the provided dataElement</li><li><a href="https://sdk.apryse.com/api/web/UI.html#.getModularHeaderList">getModularHeaderList()</a> - gets all headers</li></ul><p>New Modular APIs to return a header object, which has methods on it to set items and properties. These update dynamically in the UI. See <a href="https://sdk.apryse.com/api/web/UI.Components.ModularHeader.html">ModularHeader Class</a>.</p>                                                                                                                                                                                                                                                                                                                                                         |
| [setActiveHeaderGroup()](https://sdk.apryse.com/api/web/UI.html#.setActiveHeaderGroup)                                                                                                                                                                                                                                                                                                                                                                                                          | <ul><li><a href="https://sdk.apryse.com/api/web/UI.html#.addModularHeaders">addModularHeaders(\[dataElements])</a> - allows you to add headers to the UI</li><li><a href="https://sdk.apryse.com/api/web/UI.html#.setModularHeaders">setModularHeaders(\[dataElements])</a> - allows you to change the current list of headers</li></ul><p>Changing headers can be done simply by adding a new header or by changing out the entire list of headers with a new one. See <a href="https://sdk.apryse.com/api/web/UI.Components.ModularHeader.html">ModularHeader Class</a>.</p>                                                                                                                                                                                                                                                                                                                                 |
| [setCustomPanel()](https://sdk.apryse.com/api/web/UI.html#.setCustomPanel)                                                                                                                                                                                                                                                                                                                                                                                                                      | <ul><li><a href="https://sdk.apryse.com/api/web/UI.html#.addPanel(panelObject)">addPanel</a> - allows users to add a standalone panel to the left or right, using custom code or the existing preset panels</li><li><a href="https://sdk.apryse.com/api/web/UI.html#.getPanels()()">getPanels</a> - returns all panels</li><li><a href="https://sdk.apryse.com/api/web/UI.html#.setPanels(panelList)">setPanels</a> - sets all panels</li></ul><p>The legacy API only allows you to add a tab to the left panel. With the new APIs, you can set custom or existing panels to the left or right. If you want to add a tab to a tabbed panel (i.e., the default leftPanel), you can get the <a href="https://sdk.apryse.com/api/web/UI.Components.TabPanel.html">TabPanel</a> with <a href="https://sdk.apryse.com/api/web/UI.html#.getPanels()">getPanels</a> and add a tab to its <code>panelsList</code>.</p> |
| <p><a href="https://sdk.apryse.com/api/web/UI.MenuOverlay.html">MenuOverlay Class</a> This class implements three methods to customize the hamburger menu:</p><ul><li>getItems</li><li>add</li><li>update</li></ul>                                                                                                                                                                                                                                                                             | <ul><li><a href="https://sdk.apryse.com/api/web/UI.Components.MainMenu.html">MainMenu Flyout</a></li></ul><p>This uses the new <a href="https://sdk.apryse.com/api/web/UI.Components.Flyout.html">Flyout class</a>, which has the following methods and properties:</p><ul><li>setItems</li><li>items property</li><li>Option to instantiate with an array of items</li></ul><p>All existing legacy methods work with new Flyout.</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| <p><a href="https://sdk.apryse.com/api/web/UI.html#.pageManipulationOverlay">PageManipulation Overlay</a> Has access to methods to update and set the items in the page manipulation overlay (opened via thumbnails)</p><ul><li>getItems</li><li>add</li><li>update</li></ul><p>Also has two methods to customize onClick behaviors:</p><ul><li>disableOpeningByRightClick</li><li>enableOpeningByRightClick</li></ul><p>These APIs control if we can open this overlay with a right click.</p> | PageManipulation Overlay is now a Flyout with the same methods as the legacy overlay. It also has access to all methods and properties of the new [Flyout class](https://sdk.apryse.com/api/web/UI.Components.Flyout.html). All existing legacy methods work with new Flyout.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

## Examples

Below are some examples of how to use the new Modular UI APIs to customize the UI.

### Changing Header Items

Before

You would use the API `UI.setHeaderItems` to change the header items or the API `UI.setActiveHeaderGroup` to manipulate the header.

After

There are now different ways that [headers](/web/ui-customization/modular-ui/containers.md#modular-header) can be used in the Modular UI. You can now have multiple headers in different places in your UI. As such, there are now getters such as [UI.getModularHeader](https://sdk.apryse.com/api/web/UI.html#.getModularHeader) and [UI.getModularHeaderList](https://sdk.apryse.com/api/web/UI.html#.getModularHeaderList) which return header object that include methods to set items and properties. When headers are changed they will be updated dynamically in the UI.

You can also add new headers or change the current list of headers with the APIs [UI.addModularHeaders](https://sdk.apryse.com/api/web/UI.html#.addModularHeaders) and [UI.setModularHeaders](https://sdk.apryse.com/api/web/UI.html#.setModularHeaders).

The following example shows how to change the items in a header:

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const header = instance.UI.getModularHeader('default-top-header');
// replace all items in the default top header with a new button
header.setItems([{
  type: 'customButton',
  dataElement: 'testButton',
  label: 'My Button',
  title: 'My Button',
  onClick: () => {
    console.log('Button clicked');
  }
}]);
```

{% endcode %}
{% endtab %}
{% endtabs %}

[UI.getModularHeader](https://sdk.apryse.com/api/web/UI.html#.getModularHeader) [UI.getModularHeaderList](https://sdk.apryse.com/api/web/UI.html#.getModularHeaderList) [UI.addModularHeaders](https://sdk.apryse.com/api/web/UI.html#.addModularHeaders) [UI.setModularHeaders](https://sdk.apryse.com/api/web/UI.html#.setModularHeaders)

### Editing the Main Menu

Before

You would use the `settingsMenuOverlay` interface to customize the hamburger menu.

After

You can now use the new [Flyout](https://sdk.apryse.com/api/web/UI.Components.Flyout.html) class, which has the [setItems](https://sdk.apryse.com/api/web/UI.Components.MainMenu.html#setItems__anchor) method that you can use to change the items in the flyout. To find the flyout you want to change, you can use the [getFlyout](https://sdk.apryse.com/api/web/UI.Flyouts.html#.getFlyout) method.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
instance.UI.Flyouts.getFlyout('MainMenuFlyout').setItems([
  {
    type: 'customButton',
    className:"row",
    img: 'icon-header-print-line',
    onClick: () => {
      alert('Hello world!');
    },
    dataElement: 'alertButton',
    label:'test button',
    role:"option"
  },
  {
    type: 'customButton',
    className:"row",
    img: 'icon-header-print-line',
    onClick: () => {
      alert('Hello world!');
    },
    dataElement: 'alertButton2',
    label:'test button 2',
    role:"option"
  },
]);
```

{% endcode %}
{% endtab %}
{% endtabs %}

[UI.Components.Flyouts.getFlyout](https://sdk.apryse.com/api/web/UI.Flyouts.html#.getFlyout__anchor) [UI.Components.Flyout.setItems](https://sdk.apryse.com/api/web/UI.Components.Flyout.html#setItems__anchor)

### Moving Items into a Header

Before

In order to move items from the Main Menu to the header, it would require a lot of custom code. You would need to create a custom button for each one that you wanted to move and add that button to the header. Creating the custom button would also mean finding the APIs to call from the button's onClick method and whichever icon you wanted to use.

After

With the new Modular UI, you can easily move items from the main menu to the header by using [preset buttons](https://sdk.apryse.com/api/web/UI.Components.PresetButton.html) along with the `setItems` methods, shown above, for the main menu and header.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
// Download button from the Main Menu
const downloadButton = new instance.UI.Components.PresetButton({
  buttonType: 'downloadButton',
  dataElement: 'presetButton-download'
});

// Save As button from the Main Menu
const saveAsButton = new instance.UI.Components.PresetButton({
  buttonType: 'saveAsButton',
  dataElement: 'presetButton-save'
});

// Print button from the Main Menu
const printButton = new instance.UI.Components.PresetButton({
  buttonType: 'printButton',
  dataElement: 'presetButton-print'
});

// Settings button from the Main Menu
const settingsButton = new instance.UI.Components.PresetButton({
  buttonType: 'settingsButton',
  dataElement: 'presetButton-settings'
});

const header = instance.UI.getModularHeader('default-top-header');

// add all the buttons to the header 
header.setItems([...header.getItems(), downloadButton, saveAsButton, printButton, settingsButton]);
```

{% endcode %}
{% endtab %}
{% endtabs %}

[UI.Components.PresetButton](https://sdk.apryse.com/api/web/UI.Components.PresetButton.html) [UI.getModularHeader](https://sdk.apryse.com/api/web/UI.html#.getModularHeader)

Preset buttons are a new feature in the Modular UI that allow you to easily add buttons to the UI without having to create custom buttons. They are a great way to add buttons to the UI that already have an icon the correct onClick methods.

You can even add other [prebuilt items](/web/ui-customization/modular-ui/items.md#prebuilt-items) like the [Page Controls](/web/ui-customization/modular-ui/items.md#page-controls) to the header in the same way.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const pageControls = new instance.UI.Components.PageControls();

// This can now be added to a modular header
const header = instance.UI.getModularHeader('default-top-header')
header.setItems([...header.getItems(), pageControls]);
```

{% endcode %}
{% endtab %}
{% endtabs %}

[UI.Components.PageControls](https://sdk.apryse.com/api/web/UI.Components.PageControls.html) [UI.getModularHeader](https://sdk.apryse.com/api/web/UI.html#.getModularHeader)

You can also find some examples that show how to set up a UI config in the [UI Import and Export guide](/web/ui-customization/modular-ui/ui-import-and-export.md#examples).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/migration-guides/migrating-to-v11/migrating-to-v11-modular-ui.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
