Skip to main content

UI extensions

This page describes the UI extensions API in detail.

Extension points in Grafana

A list of available extension points within Grafana that can be extended by plugins. All these extension point IDs can be accessed using the PluginExtensionPoints enum exposed by the @grafana/data package.

import { PluginExtensionPoints } from '@grafana/data';

const extensionPointId = PluginExtensionPoints.DashboardPanelMenu;
Extension Point IDTypeDescription
AlertingAlertingRuleActionLinkExtend the alert rule menu with custom actions for alerting rules.
AlertingHomePageComponentExtend the alerting home page with custom alert-creation experience.
AlertingRecordingRuleActionLinkExtend the alert rule menu with custom actions for recording rules.
AlertInstanceActionLinkExtend the alert instances table with custom actions.
CommandPaletteLinkExtend the command palette with custom actions.
DashboardPanelMenuLinkExtend the panel menu with custom actions.
ExploreToolbarActionLinkExtend the "Add" button on the Explore page with custom actions.
UserProfileTabComponentExtend the user profile page with custom tabs.

Methods

addComponent

info

Available in Grafana >=v11.1.0.

This method can be used to register a React component to a certain extension point to contribute a new ui experience.

export const plugin = new AppPlugin<{}>().addComponent({
targets: ['grafana/user/profile/tab/v1'],
title: 'New user profile tab',
description: 'A new tab that shows extended user profile information',
component: () => {
return <div>Hello World!</div>;
},
});

Parameters

The addComponent() method takes a single config object with the following properties:

PropertyDescription
targetsA list of extension point IDs where the extension will be registered.
Example: "grafana/dashboard/panel/menu/v1". See available extension points in Grafana →
titleA human readable title for the component.
descriptionA human readable description for the component.
componentThe React component that will be rendered by the extension point. Note: the props passed to the component are defined by each extension point.

Return value

The method returns the AppPlugin instance to allow for chaining.

Examples

See also

info

Available in Grafana >=v11.1.0.

This method can be used to register a link extension to a certain extension point. Link extensions are used to navigate to different parts of the Grafana UI or other plugins, and can include modal elements declared via an onClick.

export const plugin = new AppPlugin<{}>().addLink({
targets: ['grafana/dashboard/panel/menu/v1'],
title: 'Declare incident',
description: 'Declare an incident and attach the panel context to it',
path: '/a/myorg-incidents-app/incidents',
});

Parameters

The addLink() method takes a single config object with the following properties:

PropertyDescriptionRequired
targetsA list of extension point IDs where the extension will be registered.
Example: "grafana/dashboard/panel/menu/v1". See available extension points in Grafana →
true
titleA human readable title for the link.true
descriptionA human readable description for the link.true
path?A path within your app plugin where you would like to send users when they click the link. (Use either path or onClick.)
Example: "/a/myorg-incidents-app/incidents"
true
onClick?A callback that should be triggered when the user clicks the link. (Use either path or onClick.)false
category?A category that should be used to group your link with other links.false
icon?An icon that should be used while displaying your link.
Example: "edit" or "bookmark". See all available icon names →
false
configure?A function that is called prior to displaying the link which enables you to dynamically change or hide your link depending on its context.false

Return value

The method returns the AppPlugin instance to allow for chaining.

Examples

exposeComponent

info

Available in Grafana >=v11.1.0.

This method exposes a React component and makes it available for other plugins to use. Other plugins can render the component within their app by calling usePluginComponent() and referencing the id of the exposed component.

export const plugin = new AppPlugin<{}>()
.exposeComponent({
id: "myorg-incidents-app/create-incident-form/v1",],
title: "Create incident form",
description: "A form to create a new incident.",
component: () => {
return <div>Hello World!</div>;
},
});

Parameters

The exposeComponent() method takes a single config object with the following properties:

PropertyDescription
idA unique string identifier of the component you are exposing. It must be prefixed with your plugin ID.
Example: "myorg-incidents-app/create-incident-form/v1".
titleA human readable title for the component.
descriptionA human readable description for the component.
componentA React component that you are exposing.
Make sure to wrap it with the necessary React context providers that the component is relying on, as this component is not going to be rendered under the same React tree as your plugin.

Return value

The method returns the AppPlugin instance to allow for chaining.

Examples

See also

getPluginExtensions ⚠️

This function can be used to fetch extensions (both links and components) that are registered to a certain extension point.

warning

This function is deprecated and will be removed in Grafana v12. Please use either the usePluginLinks() or usePluginComponents() hooks instead.

import { getPluginExtensions } from '@grafana/runtime';

const { extensions } = getPluginExtensions({
extensionPointId: 'grafana/dashboard/panel/menu/v1',
limitPerPlugin: 2,
context: {
panelId: '...',
},
});

Parameters

The getPluginExtensions() function takes a single options object with the following properties:

PropertyDescriptionRequired
extensionPointIdA unique id to fetch link extensions for. In case you are implementing a new extension point, this is what plugins reference when registering extensions. Plugins must prefix this with their plugin id, while core Grafana extensions points have to use a "grafana/" prefix.
Example: "grafana/dashboard/panel/menu/v1"
true
context?An arbitrary object that you would like to share with the extensions. This can be used to pass data to the extensions.false
limitPerPlugin?- The maximum number of extensions to return per plugin. Default is no limit.false

Return value

The hook returns the following object:

const {
// An empty array if no plugins have registered extensions for this extension point yet
extensions: PluginExtension[];
} = getPluginExtensions(options);

For more information, see PluginExtension.

Hooks

usePluginComponent

info

Available in Grafana >=v11.1.0.

This react hook can be used to fetch a single react component that was exposed by a plugin with a unique ID. Plugins can expose components using the AppPlugin.exposeComponent() method.

import { usePluginComponent } from '@grafana/runtime';

const { component: Component, isLoading } = usePluginComponent('myorg-incidents-app/create-incident-form/v1');

Parameters

  • id - A unique id that identifies the component.

Return value

The hook returns the following object:

const {
// The react component that was exposed by the plugin
// (`null` if no component is exposed with that id)
component: React.ComponentType<Props> | undefined | null;

// `true` until the plugin exposing the component is still loading
isLoading: boolean;
} = usePluginComponent(id);

Examples

usePluginComponents

info

Available in Grafana >=v11.1.0.

This react hook can be used to fetch components that are registered to a certain extension point. Component extensions can be used to render custom UI components. Plugins can register components using the AppPlugin.addComponent() method.

import { usePluginComponents } from '@grafana/runtime';

const { components, isLoading } = usePluginComponents({
extensionPointId: 'grafana/user/profile/tab/v1',
limitPerPlugin: 1,
});

Parameters

The .usePluginComponents() method takes a single options object with the following properties:

PropertyDescriptionRequired
extensionPointIdA unique id to fetch link extensions for. In case you are implementing a new extension point, this is what plugins reference when registering extensions. Plugins must prefix this with their plugin id, while core Grafana extensions points have to use a "grafana/" prefix.
Example: "grafana/user/profile/tab/v1"
true
limitPerPlugin?- The maximum number of extensions to return per plugin. Default is no limit.False

Return value

The hook returns the following object (for more info check PluginExtensionComponent:

const {
// An empty array if no plugins have registered extensions for this extension point yet
components: PluginExtensionComponent[];

// `true` until any plugins extending this extension point
// are still loading
isLoading: boolean;
} = usePluginComponents(options);

Examples

See also

info

Available in Grafana >=v11.1.0.

This react hook can be used to fetch links that are registered to a certain extension point. Plugins can register links using the AppPlugin.addLink() method.

import { usePluginLinks } from '@grafana/runtime';

const { links, isLoading } = usePluginLinks({
extensionPointId: 'grafana/dashboard/panel/menu/v1',
limitPerPlugin: 2,
context: {
panelId: '...',
},
});

Parameters

The .usePluginLinks() method takes a single options object with the following properties:

PropertyDescriptionRequired
extensionPointIdA unique id to fetch link extensions for. In case you are implementing a new extension point, this is what plugins reference when registering extensions. Plugins must prefix this with their plugin id, while core Grafana extensions points have to use a "grafana/" prefix.
Example: "grafana/dashboard/panel/menu/v1"
true
context?An arbitrary object that you would like to share with the extensions. This can be used to pass data to the extensions.false
limitPerPlugin?The maximum number of extensions to return per plugin. Default is no limit.false

Return value

The hook returns the following object (for more info check PluginExtensionLink):

const {
// An empty array if no plugins have registered extensions for this extension point yet
links: PluginExtensionLink[];

// `true` until any plugins extending this extension point
// are still loading
isLoading: boolean;
} = usePluginLinks(options);

Examples

See also

usePluginExtensions ⚠️

This react hook can be used to fetch extensions (both links and components) that are registered to a certain extension point.

warning

This hook is deprecated and will be removed in Grafana v12. Please use either the usePluginLinks() or usePluginComponents() hooks instead.

import { usePluginExtensions } from '@grafana/runtime';

const { extensions, isLoading } = usePluginExtensions({
extensionPointId: 'grafana/dashboard/panel/menu/v1',
limitPerPlugin: 2,
context: {
panelId: '...',
},
});

Parameters

The .usePluginExtensions() method takes a single options object with the following properties:

PropertyDescriptionRequired
extensionPointIdA unique id to fetch link extensions for. In case you are implementing a new extension point, this is what plugins reference when registering extensions. Plugins must prefix this with their plugin id, while core Grafana extensions points have to use a "grafana/" prefix.
Example: "grafana/dashboard/panel/menu/v1"
true
context?An arbitrary object that you would like to share with the extensions. This can be used to pass data to the extensions.false
limitPerPlugin?The maximum number of extensions to return per plugin. Default is no limit.false

Return value

The hook returns the following object:

const {
// An empty array if no plugins have registered extensions for this extension point yet
extensions: PluginExtension[];

// `true` until any plugins extending this extension point
// are still loading
isLoading: boolean;
} = usePluginExtensions(options);

For more information, see PluginExtension.