---
title: Render element as React - Client-side Extensions
platform: server
product: clientside-extensions
category: reference
subcategory: api
date: '2024-04-02'
---

# Render element as React

The `renderElementAsReact` function is a utility provided to render custom content using React with the Client-side Extensions API.

It handles the mount/unmount cycles and rendering/unmounting the provided component for you.
Also, it's recommended to use it since optimizations to React rendering content will be applied here in the future.

## Signature

```ts
type renderElementAsReact = <PropsT>(
    renderApi: PanelAPI | ModalApi,
    RenderElement: ComponentType<PropsT>,
    additionalProps?: PropsT,
) => void;
```

## Arguments

<table>
    <thead>
        <tr class="header">
            <th>Name</th>
            <th>Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>renderApi*</td>
            <td><code>PanelApi | ModalApi</code></td>
            <td>The API object received in the <code>onAction</code> method should be provided as the argument. Only works for Panels and Modals.</td>
        </tr>
        <tr>
            <td>RenderElement*</td>
            <td><code>ComponentType</code></td>
            <td>
                <p>A React component.</p>
                <p>Don't use JSX syntax here instead reference the React component e.g. <code>MyComponent</code> but not <code>&lt;MyComponent /&gt;</code></p>
            </td>
        </tr>
        <tr>
            <td>additionalProps</td>
            <td><code>object</code></td>
            <td>
                An optional object with additional props that will be bind to the component once mounted.
            </td>
        </tr>
    </tbody>
</table>

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

## Usage notes

### 1. Rendering a React component as content of a panel

#### `my-extension.ts`

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

import PanelContent from './panel-content';

/**
 * @clientside-extension
 * @extension-point reff.plugins-example-location
 */
export default PanelExtension.factory(() => {
    return {
        label: `React panel`,
        onAction(panelApi) {
            renderElementAsReact(panelApi, PanelContent);
        },
    };
});
```

#### `panel-content.ts`

```jsx
const PanelContent = () => {
    return <p>Hello World!</p>;
};

export default PanelContent;
```

### 2. Rendering a React component as content of an asynchronous panel with additional props

#### `my-extension.ts`

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

const moduleLoader = () => import('./my-panel');

/**
 * @clientside-extension
 * @extension-point reff.plugins-example-location
 */
export default AsyncPanelExtension.factory<MyContext>(() => {
    return {
        label: `React async panel`,
        onAction: moduleLoader,
    };
});
```

#### `my-panel.ts`

<!-- prettier-ignore-start -->
```ts
import { PanelExtension, renderElementAsReact } from '@atlassian/clientside-extensions-components';
import MyPanelContent, { MyPanelContentProps } from './my-panel-content';
import { MyContext } from './types';

export default function initAsyncPanel(
  panelApi: PanelExtension.Api,
  context: MyContext
) {
    renderElementAsReact<MyPanelContentProps>(panelApi, MyPanelContent, { context });
}
```
<!-- prettier-ignore-end -->

#### `my-panel-content.ts`

```ts
import React from 'react';
import { MyContext } from './types';

export type MyPanelContentProps = {
    context: MyContext;
};

const MyPanelContent: React.FC<MyPanelContentProps> = ({ context }) => {
    return <p>Hello ${context.label}!</p>;
};

export default MyPanelContent;
```

#### `types.ts`

```ts
export type MyContext {
    label: string;
}
```

### 3. Rendering a React component as content of a modal with additional props

```ts
import { ModalExtension } from '@atlassian/clientside-extensions';
import { renderElementAsReact } from '@atlassian/clientside-extensions-components';
import React from 'react';

type MyContext = {
    /*...*/
}

type ReactComponentProps = {
    context: MyContext;
    modalAPI: ModalExtension.Api;
};

const ReactComponent: React.FC<ReactComponentProps> = ({ context, modalAPI }) => {
    modalAPI.setTitle('An awesome modal with react');

    modalAPI.onClose(() => {
        /*...*/
    });

    modalAPI.setActions([
        /*...*/
    ]);

    return ( /*..Your custom modal content goes here..*/);
};

/**
 * @clientside-extension
 * @extension-point reff.plugins-example-location
 */
export default ModalExtension.factory<MyContext>((pluginApi, context) => {
    return {
        label: `Modal with react content`,
        onAction(modalAPI) {
            renderElementAsReact<ReactComponentProps>(
              modalAPI,
              ReactComponent,
              { modalAPI, context }
            );
        },
    };
});
```
