Skip to main content

Register an extension from your app plugin

Before you begin

Be sure your plugin meets the following requirements before proceeding:

  • It must be an app plugin.
  • It must be preloaded by setting the preload property to true in the plugin.json.
  • It must be installed and enabled for the extension to be available.

How to extend the Grafana UI or an app plugin from your app plugin

Add the configureExtensionLink method in your module.ts(x) file to register extensions. This requires an object containing the following properties:

  • extensionPointId required - the unique identifier of the extension point you would like to extend. See available extension points within Grafana.
  • title required - used to display your extension at the extension point.
  • description required - short description of what your extension does.
  • path - a path within your app plugin where you would like to send users when they click the extension.
  • onClick - a callback that should be triggered when the user clicks the extension.
  • category - a category that we should use to group your extension with other extensions.
  • icon - an icon that should be used while displaying your extension.
  • configure - a function that is called prior to displaying the extension which enables you to dynamically change or hide your extension depending on its context.
warning

Use either path or onClick (only one is required) otherwise the extension will be hidden.

In the following example, we add an extension link to the Grafana dashboard panel menu. When the user clicks "Go to basic app," they are sent to /a/myorg-basic-app/one.

src/module.ts
new AppPlugin().configureExtensionLink({
title: 'Go to basic app',
description: 'Will send the user to the basic app',
extensionPointId: 'grafana/dashboard/panel/menu',
path: '/a/myorg-basic-app/one', // Must start with "/a/<PLUGIN_ID>/"
});

In the following example, we add an extension link to the Grafana dashboard panel menu. When the user clicks "Go to basic app," they are sent to /a/myorg-basic-app/one?panelId=12345&timeZone=utc.

src/module.ts
import { AppPlugin, PluginExtensionPanelContext } from '@grafana/data';

new AppPlugin().configureExtensionLink({
title: 'Go to basic app',
description: 'Will send the user to the basic app',
extensionPointId: 'grafana/dashboard/panel/menu',
path: '/a/myorg-basic-app/one', // Must start with "/a/<PLUGIN_ID>/"
configure: (context: PluginExtensionPanelContext) => {
const { timeZone, panelId } = context;

// You only need to return the properties that you would like to override.
return {
path: `/a/myorg-basic-app/one?panelId=${panelId}&timeZone=${timeZone}`,
};
},
});

In the following example, we add an extension link to the Grafana dashboard panel menu. It will only be visible for panels with the time zone set to UTC.

src/module.ts
import { AppPlugin, PluginExtensionPanelContext } from '@grafana/data';

new AppPlugin().configureExtensionLink({
title: 'Go to basic app',
description: 'Will send the user to the basic app',
extensionPointId: 'grafana/dashboard/panel/menu',
path: '/a/myorg-basic-app/one', // Must start with "/a/<PLUGIN_ID>/"
configure: (context: PluginExtensionPanelContext) => {
const { timeZone } = context;

switch (toLowerCase(timeZone)) {
case 'utc':
return {}; // no overrides applied but we want to display the extension.
default:
return undefined; // returning undefined from the configure function will hide the extension.
}
},
});

Example: Display a modal view

In the following example, we add an extension link to the Grafana dashboard panel menu. It will open a flow (defined in our app) in a modal on top of the current view.

src/module.ts
new AppPlugin().configureExtensionLink({
title: 'Create incident',
description: 'Will open a prefilled form to create an incident.',
extensionPointId: 'grafana/dashboard/panel/menu',
onClick: (event, params) => {
const { context, openModal } = params;
const { targets = [], title } = context;

openModal({
title: 'Create incident',
body: (props) => <CreateIncidentForm {...props} title={title} targets={targets}>
});
}
});

Example: Display a React component

note

Available in Grafana >=10.1.0
(Component type extensions are only available in Grafana 10.1.0 and above.)

Using React components as extensions is a powerful way to extend the functionality of an existing UI either in core Grafana or in another plugin.

src/module.ts
new AppPlugin().configureExtensionComponent({
title: 'My component extension',
description: 'Renders a button at a pre-defined extension point.',
extensionPointId: 'grafana/<extension-point-id>',
component: MyExtension,
});
src/components/MyExtension.tsx
export const MyExtension = () => (
<Button onClick={() => {}} variant="secondary" type="button">
Extend UI
</Button>
);

Example: Use the context of the extension point in a component

note

Available in Grafana >=10.1.0
(Component type extensions are only available in Grafana 10.1.0 and above.)

Extension points can pass contextual information to the extensions they render; we refer to this data as context. Extension points defined in core Grafana additionally have a type definition available for these context objects. In the following example, we use this context in our component extension and also show how to use the static types.

src/module.ts
// This could also come from another plugin or defined manually if a plugin doesn't expose it.
import { PluginExtensionSampleContext } from '@grafana/data';

new AppPlugin().configureExtensionComponent<PluginExtensionSampleContext>({
title: 'My component extension',
description: 'Renders a button at a pre-defined extension point.',
extensionPointId: 'grafana/<extension-point-id>',
component: MyExtension,
});
src/components/MyExtension.tsx
type Props = {
context: PluginExtensionSampleContext;
};

export const MyExtension = ({ context }: Props) => (
<Button onClick={() => {}} variant="secondary" type="button">
Create incident from {context.name}
</Button>
);

Example: Access plugin information in a component extension

note

Available in Grafana >=10.3.0
(The usePluginMeta() and usePluginJsonDataAvailable() hooks are only available in Grafana 10.3.0 and above.)

If you would like to access meta information about your plugin from within the component extension, @grafana/data exposes some React hooks to make it possible:

src/module.ts
new AppPlugin().configureExtensionComponent({
title: 'My component extension',
description: 'Renders a button at a pre-defined extension point.',
extensionPointId: 'grafana/<extension-point-id>',
component: MyExtension,
});
src/components/MyExtension.tsx
import { usePluginMeta, usePluginJsonData } from '@grafana/data';

export const MyExtension = () => {
const meta = usePluginMeta();
const jsonData = usePluginJsonData();

if (meta.info.version !== '1.0.0') {
return null;
}

return (
<Button onClick={() => {}} variant="secondary" type="button">
Create incident ({jsonData.postFix})
</Button>
);
};

Example: Add an item to Grafana's command palette

note

Available in Grafana >=10.3.0
(The grafana/commandpalette/action extension point is only available in Grafana 10.3.0 and above.)

src/module.ts
new AppPlugin().configureExtensionComponent({
title: 'Frobnicate dashboards',
description: 'Opens a modal where the user can frobnicate dashboards',
extensionPointId: 'grafana/commandpalette/action',
onClick: (event, { openModal }) => {
openModal({
title: 'Frobnicate dashboards',
body: (props) => <MyModalComponent {...props} />,
});
},
});

Available extension points within Grafana

An extension point is a location within the Grafana UI where a plugin can insert links. The IDs of all extension points within Grafana start with grafana/. For example, you can use the following extension point ID:

  • grafana/alerting/instance/action: extension point for actions in alert instance table in alerting
  • grafana/commandpalette/action: extension point for commands in command palette
  • grafana/dashboard/panel/menu: extension point for all panel dropdown menus in dashboards
  • grafana/explore/toolbar/action: extension point for toolbar actions in explore
  • grafana/user/profile/tab: extension point for a tab of content on the /profile page