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

# Hooks and Components

CSE provides a set of React hooks and components to consume the extensions registered for a given extension point.
These hooks and components will receive an optional context, and validate the resulting attributes against the
provided schema.

Take for example the following schema file:

`schema.cse.graphql`

```graphql
"""
---
extensionPoint: example.extension-point
---
"""
type Schema {
    type: LinkExtension!

    label: string!

    url: string!
}

type ContextSchema {
    issueKey: String
}
```

You can import the hooks and components directly from the schema file, and the loader will transform the file
into a module that contains all the hooks and components already configured to use the schema provided.

## useExtensions

Receives an optional context object, retrieves the extensions registered for the extension point declared in the
schema, validates them and return an array of only valid extensions.

### Signature

```ts
import type { ExtensionDescriptor, Context } from '@atlassian/clientside-extensions-registry';

type useExtensions = (context: Context<{}>) => ExtensionDescriptor[];
```

### Usage

```jsx
import React from "react";
import { useExtensions } from "./schema.cse.graphql";

const ExampleExtensionPoint = ({ context }) => {
    const extensions = useExtensions(context);

    return (
        <>
            {extensions.map(({ attributes }) => (
              <a href={attributes.url} key={attributes.key}>{attributes.label}</a>
            )}
        </>
    )
}

export default ExampleExtensionPoint;
```

## useExtensionsLoadingState

Use this hooks in order to indicate the users that the extensions are loading.

### Signature

```ts
import type { Context } from '@atlassian/clientside-extensions-registry';

type useExtensionsLoadingState = (context: Context<{}>) => boolean;
```

### Usage

```jsx
import React from "react";
import { useExtensions, useExtensionsLoadingState } from "./schema.cse.graphql";

const ExampleExtensionPoint = ({ context }) => {
    const extensions = useExtensions(context);
    const loading = useExtensionsLoadingState(context);

    return (
        <>
            {loading ? "loading..." : extensions.map(({ attributes }) => (
                <a href={attributes.url} key={attributes.key}>{attributes.label}</a>
            )}
        </>
    )
}

export default ExampleExtensionPoint;
```

## useExtensionsUnsupported

Receives an optional context object, retrieves the extensions registered for the extension point and return a list
of all the extensions that don't pass the validation against the schema.

This is particularly useful in case you need to support legacy `WebItems` that are created only using XML definitions
inside `atlassian-plugin.xml`.

### Signature

```ts
import type { ExtensionDescriptor, Context } from '@atlassian/clientside-extensions-registry';

type useExtensionsUnsupported = (context: Context<{}>) => ExtensionDescriptor[];
```

### Usage

```jsx
import React from "react";
import { useExtensionsUnsupported } from "./schema.cse.graphql";

const ExampleExtensionPoint = () => {
    const extensions = useExtensionsUnsupported(null);

    return (
        <>
            {extensions.map((extension) => (
              <a href={extension.url} key={extension.key}>{extension.label}</a>
            )}
        </>
    )
}

export default ExampleExtensionPoint;
```

## useExtensionsAll

You can use `useExtensionsAll` in case you need all the results from `useExtensions`, `useExtensionsLoadingState`
and `useExtensionsLoadingState` and prefer to get the results with a single hook.

### Signature

```ts
import type { ExtensionDescriptor, Context } from '@atlassian/clientside-extensions-registry';

/**
 * @return [extensions, unsupported extensions, loading state]
 */
type useExtensionsAll = (context: Context<{}>) => [ExtensionDescriptor[], ExtensionDescriptor[], boolean];
```

### Usage

```jsx
import React from "react";
import { useExtensionsAll } from "./schema.cse.graphql";

const ExampleExtensionPoint = ({context}) => {
    const [extensions, unsupportedExtensions, loading] = useExtensionsAll(context);

    return (
        <>
            <h2>Extensions</h2>
            {loading ? "loading..." : extensions.map((extension) => (
                {/*...render as needed*/}
            )}

            <h2>Unsupported Extensions</h2>
            {loading ? "loading..." : unsupportedExtensions.map((extension) => (
                {/*...render as needed*/}
            )}
        </>
    )
}

export default ExampleExtensionPoint;
```

## ExtensionPoint

You can use the `ExtensionPoint` component in case you prefer it over hooks. Keep in mind that it is using the
hook internally, so you will need a compatible React version.

The component provides the same information as `useExtensionsAll`.

### Signature

```ts
import type { ExtensionDescriptor, Context } from '@atlassian/clientside-extensions-registry';

type ExtensionPoint = (props: { context: Context<{}> }) => (
  ExtensionDescriptor[],
  ExtensionDescriptor[],
  boolean,
) => JSX.Element;
```

### Usage

```jsx
import React from "react";
import { ExtensionPoint } from "./schema.cse.graphql";

const ExampleExtensionPoint = ({context}) => {
    return (
        <ExtensionPoint context={context}>
            {(extensions, unsupportedExtensions, loading) => (
                <>
                    <h2>Extensions</h2>
                    {loading ? "loading..." : extensions.map((extension) => (
                        {/*...render as needed*/}
                    )}

                    <h2>Unsupported Extensions</h2>
                    {loading ? "loading..." : unsupportedExtensions.map((extension) => (
                        {/*...render as needed*/}
                    )}
                </>
            )}
        </ExtensionPoint>
    )
}

export default ExampleExtensionPoint;
```

## ExtensionPointInfo

You can add this component to share with extension developers the schema of your extension points
and highlight their locations in the current screen.

The information will only be available if the product has enabled their display in development mode.

### Usage

```jsx
import React from "react";
import { useExtensions, useExtensionsLoadingState, ExtensionPointInfo } from "./schema.cse.graphql";

const ExampleExtensionPoint = ({ context }) => {
    const extensions = useExtensions(context);
    const loading = useExtensionsLoadingState(context);

    return (
        <>
          <h2>Example extension point <ExtensionPointInfo /></h2>
          {loading ? "loading..." : extensions.map(({ attributes }) => (
            <a href={attributes.url} key={attributes.key}>{attributes.label}</a>
          )}
        </>
    )
}

export default ExampleExtensionPoint;
```
