---
title: CSE webpack plugin - Client-side Extensions
platform: server
product: clientside-extensions
category: reference
subcategory: webpack
date: '2024-04-02'
---

# Annotations

The provided webpack plugin uses annotations in comments to gather information about the extension, and generate the XML for you.

## 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>@weight</code></td>
            <td><code>number</code></td>
            <td>
                <p>Determines the order in which the 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>@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="/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>

## Deprecated annotations

The following annotations should no longer be used

<table>
    <colgroup>
        <col width="25%" />
        <col width="25%" />
        <col width="25%" />
        <col width="25%" />
    </colgroup>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Deprecated since</th>
            <th>Planned removal</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>@label</code></td>
            <td><code>string</code></td>
            <td align="right">2.0</td>
            <td align="right">3.0</td>
        </tr>
        <tr>
            <td><code>@link</code></td>
            <td><code>string</code></td>
            <td align="right">2.0</td>
            <td align="right">3.0</td>
        </tr>
    </tbody>
</table>

Instead of specifying the following as annotations it is recommended to provide these as attributes at runtime:

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

/**
 * @clientside-extension
 * @extension-point example.extension.point
 * @weight 100
 */
export default LinkExtension.factory((api) => {
    return {
        label: 'My Link-Extension',
        url: '/my-link-extension',
    };
});
```

### Supported <code>PageExtension</code> annotations

The list of additional annotation that can be used with [`PageExtension`]. Refer to the [`PageExtension` API](/server/framework/clientside-extensions/reference/api/extension-factories/page/) to read more details about the 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>@page-url</code> <strong>*</strong></td>
            <td><code>string</code></td>
            <td>
                <p>Defines an url of the web page. The page will be accessible at this url prefixed with <code>/plugins/servlet/&lt;&lt;page-url&gt;&gt;</code></p>
                <p><strong>Example</strong>: Using <code>@page-url /labels</code> will register the page at <code>/plugins/servlet/labels</code> URL.</p>
            </td>
        </tr>
        <tr>
            <td><code>@page-title</code> <strong>*</strong></td>
            <td><code>string</code></td>
            <td>Defines a title of the web page. The value can be either a raw string or a property key than will be translated.</td>
        </tr>
        <tr>
            <td><code>@page-decorator</code></td>
            <td><code>string</code></td>
            <td>
                <p>A custom page decorator. The default value is <code>atl.general</code>. To read more about page decorators <a href="/server/framework/atlassian-sdk/using-standard-page-decorators">refer to the documentation</a>.</p>
                <p>List of built-in decorators supported by all products:</p>
                <ul>
                    <li><code>atl.admin</code></li>
                    <li><code>atl.general</code></li>
                    <li><code>atl.popup</code></li>
                    <li><code>atl.userprofile</code></li>
                </ul>
            </td>
        </tr>
        <tr>
            <td><code>@page-data-provider</code></td>
            <td><code>string</code></td>
            <td>
                <p>A page data provider Java class. Page data providers can be used to provide a custom set of a server-side data into your browser page extension.</p>
                <p>To read more about the page data providers check the usage section.</p>
                <p><strong>Example</strong>: <code>@page-data-provider com.example.plugin.MyDataProvider</code></p>
            </td>
        </tr>
    </tbody>
</table>

<p><strong>* required for <code>PageExtension</code></strong></p>

## Keywords

<table>
    <colgroup>
        <col width="20%" />
        <col width="80%" />
    </colgroup>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>$key</td>
            <td>When present in any annotation, $key will be replaced with the extension key generated by the CSE webpack plugin.</td>
        </tr>
    </tbody>
</table>

## Usage notes

### 1. Define a client-side extension, and the extension location to be rendered in

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

/**
 * @clientside-extension
 * @extension-point example.extension.point
 */
export default LinkExtension.factory(/*...*/);
```

### 2. Specify a weight

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

/**
 * @clientside-extension
 * @extension-point example.extension.point
 * @weight 100
 */
export default LinkExtension.factory(/*...*/);
```

### 3. Using the `page-*` annotations

The `page-*` annotations can be used to create a custom web and render a navigation link in the product UI.

```ts
/**
 * @clientside-extension
 * @extension-point example.extension.point
 * @page-url /my-admin-page
 * @page-title "My admin page"
 * @page-decorator atl.admin
 */
export default PageExtension.factory((container) => {
    container.innerHTML = '<div>Very secure page!</div>';
});
```

Refer to the [`PageExtension` API](/server/framework/clientside-extensions/reference/api/extension-factories/page/) to read more details about the supported annotations.

<!-- prettier-ignore-start -->
### 4. Using $key keyword
<!-- prettier-ignore-end -->

For those cases where you need to know the value of the extension key and use it in the annotations, you can make use of the `$key` keyword.
CSE webpack plugin will replace it with the actual value of the key that the plugin generates for your extension.

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

/**
 * @clientside-extension
 * @extension-point example.extension.point
 * @page-url /my-admin-page?q=$key
 * @page-title "My admin page"
 */
export default PageExtension.factory((container) => {
    container.innerHTML = '<div>Very secure page!</div>';
});
```

### 5. Define a condition

The `@condition` annotation allows you to define one or multiple conditions that must be satisfied for the extension to be displayed.
These conditions are a web-resource conditions evaluated in the server, and created with Java.

For more information about the condition's usage please refer to the [examples of Web items documentation](https://developer.atlassian.com/server/framework/atlassian-sdk/web-section-plugin-module/#condition-and-conditions-elements) and check the [documentation of `conditionMap` option from `atlassian-webresource-webpack-plugin`](https://www.npmjs.com/package/atlassian-webresource-webpack-plugin#conditionmap-optional).

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

/**
 * @clientside-extension
 * @extension-point example.extension.point
 * @condition class com.atlassian.cse.demo.RandomCondition
 */
export default LinkExtension.factory(/*...*/);
```

### 6. Define a condition with parameters

To add parameters to the conditions you can use multiple `@condition` annotations. These parameters will be passed in to the condition's `init()` method as a map of string key/value pairs.

The first part of `@condition` annotation is a property path, and the second part is the property value.

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

/**
 * @clientside-extension
 * @extension-point example.extension.point
 * @condition class com.atlassian.cse.demo.RandomCondition
 * @condition params.0.attributes.name permission
 * @condition params.0.value admin
 * @condition params.1.attributes.name location
 * @condition params.1.value menu
 */
export default LinkExtension.factory(/*...*/);
```

These `@condition` annotations will result in creating a condition map object that is matching the [shape of `conditionMap` option from `atlassian-webresource-webpack-plugin`](https://www.npmjs.com/package/atlassian-webresource-webpack-plugin#conditionmap-optional):

```json
{
    "class": "com.atlassian.cse.demo.RandomCondition",
    "params": [
        {
            "attributes": {
                "name": "permission"
            },
            "value": "admin"
        },
        {
            "attributes": {
                "name": "location"
            },
            "value": "menu"
        }
    ]
}
```

### 7. Defining multiple conditions

You can make use of AND / OR keywords to combine multiple conditions for your extension as follows:

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

/**
 * @clientside-extension
 * @extension-point example.extension.point
 * @condition type AND
 * @condition conditions.0.type OR
 * @condition conditions.0.conditions.0.class com.atlassian.cse.demo.RandomCondition
 * @condition conditions.0.conditions.0.invert true
 * @condition conditions.0.conditions.0.params.0.attributes.name permission
 * @condition conditions.0.conditions.0.params.0.value admin
 * @condition conditions.0.conditions.1.class com.atlassian.cse.demo.SuperCondition
 * @condition conditions.0.conditions.1.invert true
 * @condition conditions.0.conditions.1.params.0.attributes.name permission
 * @condition conditions.0.conditions.1.params.0.value project
 * @condition conditions.1.class com.atlassian.cse.demo.PerfecCondition
 * @condition conditions.1.params.0.attributes.name permission
 * @condition conditions.1.params.0.value admin
 */
export default LinkExtension.factory(/*...*/);
```

These `@condition` annotations will result in creating a condition map object that is matching the [shape of `conditionMap` option from `atlassian-webresource-webpack-plugin`](https://www.npmjs.com/package/atlassian-webresource-webpack-plugin#conditionmap-optional):

```json
{
    "type": "AND",
    "conditions": [
        {
            "type": "OR",
            "conditions": [
                {
                    "class": "com.atlassian.cse.demo.RandomCondition",
                    "invert": true,
                    "params": [
                        {
                            "attributes": {
                                "name": "permission"
                            },
                            "value": "admin"
                        }
                    ]
                },
                {
                    "class": "com.atlassian.cse.demo.SuperCondition",
                    "invert": true,
                    "params": [
                        {
                            "attributes": {
                                "name": "permission"
                            },
                            "value": "project"
                        }
                    ]
                }
            ]
        },
        {
            "class": "com.atlassian.cse.demo.PerfectCondition",
            "params": [
                {
                    "attributes": {
                        "name": "permission"
                    },
                    "value": "admin"
                }
            ]
        }
    ]
}
```
