---
title: Modal API - Client-side Extensions
platform: server
product: clientside-extensions
category: reference
subcategory: api
date: '2024-09-24'
---

# Modal API

## About

API to render and manipulate extensions of type Modal.

### Signature

```ts
type ModalAction = {
    text: string;
    onClick: () => void;
    isDisabled?: boolean;
    isLoading?: boolean;
    testId?: string;
};

type ModalCloseCallback = (e: MouseEvent) => boolean;

type LifecycleCallback = (container: HTMLElement) => void;

enum ModalAppearance {
    'danger' = 'danger',
    'warning' = 'warning',
}

enum ModalWidth {
    'small' = 'small',
    'medium' = 'medium',
    'large' = 'large',
    'x-large' = 'x-large',
}

interface ModalApi {
    setTitle: (title: string) => ModalApi;

    setWidth: (width: ModalWidth) => ModalApi;

    setAppearance: (appearance: ModalAppearance) => ModalApi;

    closeModal: () => ModalApi;

    onMount: (callback: LifecycleCallback) => ModalApi;

    onUnmount: (callback: LifecycleCallback) => ModalApi;

    setActions: (actions: ModalAction[]) => ModalApi;

    onClose: (callback: ModalCloseCallback) => ModalApi;
}
```

## setTitle()

Allows setting a title for the modal.

### Arguments

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>title*</td>
            <td><code>string</code></td>
            <td>A string to serve as the title of the modal.</td>
        </tr>
    </tbody>
</table>

<p><strong>* required</strong></p>

### Usage

```ts
import { ModalExtension } from '@atlassian/clientside-extensions';

/**
 * @clientside-extension
 * @extension-point reff.plugins-example-location
 */
export default ModalExtension.factory((extensionAPI, context) => {
    return {
        label: 'Open Modal',
        onAction(modalAPI) {
            modalAPI.setTitle('A cool modal with JS');
        },
    };
});
```

## setWidth()

Allows specifying a width for the modal.

### Arguments

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Values</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>width*</td>
            <td><code>"small" | "medium" | "large" | "x-large"</code></td>
        </tr>
    </tbody>
</table>

## setAppearance()

Allows specifying an appearance for the modal.

### Arguments

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Values</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>appearance*</td>
            <td><code>"danger" | "warning"</code></td>
        </tr>
    </tbody>
</table>

## closeModal()

When executed, it will close the modal.

## onMount()

Provides a container to render custom content as the body of the modal, and provides an API to interact with the modal once opened.

### Callback parameters

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>container</td>
            <td><code>HTMLElement</code></td>
            <td>HTML element to be used as a container to render custom content in the body of the modal.</td>
        </tr>
    </tbody>
</table>

## setActions()

Allows to specify the actions as buttons in the footer of the modal.

### Arguments

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>actions*</td>
            <td><code>ModalAction[]</code></td>
            <td>
                <p>Actions for the modal. It supports the following properties:</p>
                <p>
                    <strong>text:</strong> text content for the button.
                </p>
                <p>
                    <strong>onClick:</strong> callback to execute when the button is clicked.
                </p>
                <p>
                    <strong>isDisabled:</strong> if true, the button will be rendered in a disabled state.
                </p>
                <p>
                    <strong>isLoading:</strong> if true, the button will be rendered in a loading state.
                </p>
                <p>
                    <strong>testId:</strong> a unique string that appears as a data attribute <code>data-testid</code> on the rendered action element
                </p>
            </td>
        </tr>
    </tbody>
</table>

<p><strong>* required</strong></p>

## onClose()

Allows to be notified when the modal is about to be closed from an external action, like the user clicking away from the modal.

### Arguments

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>callback</td>
            <td><code>ModalCloseCallback</code></td>
            <td>Callback that will get called before the modal is closed. If returning false, it will prevent the modal from close; otherwise, the modal will close.</td>
        </tr>
    </tbody>
</table>

## onUnmount()

Allows to set a cleanup callback to be called when the modal container is about to be deleted.

### Callback Parameters

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>container</td>
            <td><code>HTMLElement</code></td>
            <td>HTML element that was provided to render custom content in it. It's important to unmount any React component
            you've mounted in there to avoid keeping the component alive when the container is destroyed.</td>
        </tr>
    </tbody>
</table>

## Usage

```ts
import { ModalExtension } from '@atlassian/clientside-extensions';

import { getModalContent, confirm, primaryAction, secondaryAction } from './modal';

/**
 * @clientside-extension
 * @extension-point reff.plugins-example-location
 */
export default ModalExtension.factory((extensionAPI, context) => {
    return {
        label: 'Open Modal',
        onAction(modalAPI) {
            modalAPI.setTitle('A cool modal with JS');
            modalAPI.setWidth('small');
            modalAPI.setAppearance('warning');

            modalAPI.onMount((container) => {
                // append your content for the modal
                container.innerHTML = getModalContent();

                // set actions for the modal
                modalAPI.setActions([
                    {
                        text: 'Primary',
                        onClick: () => {
                            primaryAction().then(() => {
                                modalAPI.closeModal();
                            });
                        },
                    },
                    {
                        text: 'Secondary',
                        onClick: () => {
                            container.innerHTML = getModalContent({ secondaryClicked: true });
                        },
                    },
                ]);

                // listen when the modal is about to be closed by the user
                modalAPI.onClose(() => {
                    return confirm('Are you sure you want to close this modal?');
                });
            });
        },
    };
});
```
