---
title: Panel - Client-side Extensions
platform: server
product: clientside-extensions
category: reference
subcategory: api
date: '2024-04-18'
---

# Panel

A panel extension allows the creation of custom HTML content in a container provided by the plugin system.

## Supported attributes

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>weight</code></td>
            <td><code>number</code></td>
            <td>
                <p>Determines the order in which this extension appears respect to others in the same location.</p>
                <p>Extensions are displayed top to bottom or left to right in order of ascending weight.</p>
            </td>
        </tr>
        <tr>
            <td><code>onAction</code> <strong>*</strong></td>
            <td><code>function</code></td>
            <td>
                <p><strong>signature: </strong> <code>(panelAPI) => void</code></p>
                <p>Method to be called when the product is ready to render the panel. The plugin system will provide an API with lifecycles to render/clean up any current content into a provided container.</p>
                <p>Refer to <a href="/server/framework/clientside-extensions/reference/api/extension-api/panel-api">Panel API</a> documentation for more info.</p>
            </td>
        </tr>
    </tbody>
</table>

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

{{% tip %}}
Always remember to check the documentation of each product's extension point and supported attributes.

Read more information about [Revealing extension points on the page](/server/framework/clientside-extensions/guides/introduction/discovering-extension-points/#revealing-extension-points-on-the-page).
{{% /tip %}}

## Supported annotations

<table>
    <colgroup>
        <col width="30%" />
        <col width="10%" />
        <col width="60%" />
    </colgroup>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>@clientside-extension</code> <strong>*</strong></td>
            <td><code>-</code></td>
            <td>Indicates that the next function is an extension factory to be consumed by the webpack plugin.</td>
        </tr>
        <tr>
            <td><code>@extension-point</code> <strong>*</strong></td>
            <td><code>string</code></td>
            <td>Defines the location where the extension will be rendered.</td>
        </tr>
        <tr>
            <td><code>@condition</code></td>
            <td><code>string | Conditions</code></td>
            <td>
                <p>Defines one or multiple conditions that must be satisfied for the extension to be displayed.</p>
                <p>The conditions are evaluated on the server, and created with Java.</p>
                <p>If one of the conditions is not met, the code of the extension won't be loaded in the client.</p>
                <p>For more information about the conditions please refer to the <a href="https://developer.atlassian.com/server/framework/atlassian-sdk/web-section-plugin-module/#condition-and-conditions-elements">examples of Web items documentation</a>.</p>
            </td>
        </tr>
    </tbody>
</table>

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

## Usage

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

/**
 * @clientside-extension
 * @extension-point reff.plugins-example-location
 */
export default PanelExtension.factory(() => {
    return {
        onAction: (panelApi) => {
            panelApi
                .onMount((container) => {
                    // use the container to render your content in it
                })
                .onUnmount((container) => {
                    // run your clean up code. e.g. stop listening to events, unmount your component from the container.
                });
        },
    };
});
```

### With context definition

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

interface ExampleContext {
    issueId: string;
    title: string;
}

/**
 * @clientside-extension
 * @extension-point reff.plugins-example-location
 */
export default PanelExtension.factory<ExampleContext>((extensionAPI, context) => {
    return {
        onAction(panelApi) {
            panelApi.onMount((container) => {
                container.innerHTML = `
                  <h1>${context.title}</h1>
                  <p>Jira issue id: ${context.issueId}</p>
                `;
            });
        },
    };
});
```
