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

# AsyncPanel API

## About

API to render and manipulate extensions of type `AsyncPanel`. This API works similar to the [Panel API](/server/framework/clientside-extensions/reference/api/extension-api/panel-api). The only difference is the behavior of `onAction` attribute function.

You should use [dynamic imports](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports) syntax inside the `onAction` function to defer loading the panel module. The `onAction` function must return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) instance.

The `AsyncPanel` extension can be used to defer loading of the panel JavaScript module until the extension is initialized by the product runtime.

### Signature

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

interface AsyncPanelApi {
    onMount: (callback: LifecycleCallback) => AsyncPanelApi;

    onUnmount: (callback: LifecycleCallback) => AsyncPanelApi;
}
```

## onMount()

Provides a container to render custom content in it.

### 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.</td>
        </tr>
    </tbody>
</table>

## onUnmount()

Allows to set a cleanup callback to be called when the provided 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 example

### `my-extension.ts`

```ts
import { AsyncPanelExtension } from '@atlassian/clientside-extensions';
import { ExampleContext } from './types';

// Dynamic module loader
const panelModuleLoader = () => {
    return import('./panel-module.ts');
};

/**
 * @clientside-extension
 * @extension-point reff.plugins-example-location
 */
export default AsyncPanelExtension.factory<ExampleContext>((pluginAPI, context) => {
    return {
        onAction: panelModuleLoader,
    };
});
```

### `panel-module.ts`

<!-- prettier-ignore-start -->
```ts
import { AsyncPanelExtension } from '@atlassian/clientside-extensions';
import { ExampleContext } from './types';

function getPanelContent() {
    return `
        <h4>Cool panel</h4>
        <p>This is some cool content generated with JS</p>
    `;
}

export default function initAsyncPanel(
  panelApi: AsyncPanelExtension.Api,
  context: ExampleContext
) {
    panelApi.onMount(container => {
        container.innerHTML = getPanelContent();
    });
}
```
<!-- prettier-ignore-end -->

### `types.ts`

```ts
export interface ExampleContext {
    label: string;
}
```
