Skip to main content

Migrate plugins from Grafana version 11.6.x to 12.0.x

This guide helps you migrate plugins from Grafana version 11.6.x to 12.0.x.

Prerequisites​

Before starting the migration:

  • Back up your plugin code
  • Ensure your development environment is up to date
  • Familiarize yourself with the reactive APIs introduced in Grafana 11.4

Deprecated UI extension APIs removal​

The deprecated UI extension APIs have been removed in Grafana 12 in favor of the new reactive APIs introduced in Grafana 11.4. The following APIs have been removed:

  • usePluginExtensions()
  • usePluginLinkExtensions()
  • usePluginComponentExtensions()
  • getPluginExtensions()
  • getPluginLinkExtensions()
  • getPluginComponentExtensions()
  • AppPlugin.configureExtensionLink()
  • AppPlugin.configureExtensionComponent()

Using any of these APIs in Grafana 12 will result in an error. Additionally, the TypeScript types PluginExtensionLinkConfig and PluginExtensionComponentConfig have been removed.

info

If you need your plugin to work with both Grafana 12.0.x and older versions, you can implement runtime checks to conditionally use the appropriate APIs. For more information, refer to Manage backwards compatibility with runtime checks.

Replace the configureExtensionLink method with the addLink method. Update the extensionPointId parameter to targets, which accepts either a string or string[].

- new AppPlugin().configureExtensionLink({
+ new AppPlugin().addLink({
- extensionPointId: PluginExtensionPoints.DashboardPanelMenu,
+ targets: PluginExtensionPoints.DashboardPanelMenu,
title: 'Component title 0',
description: 'Component description 0',
component: () => <div />,
});

AppPlugin.configureExtensionComponent()​

Replace the configureExtensionComponent method with the addComponent method. Update the extensionPointId parameter to targets, which accepts either a string or string[].

- new AppPlugin().configureExtensionComponent({
+ new AppPlugin().addComponent({
- extensionPointId: PluginExtensionPoints.CommandPalette,
+ targets: PluginExtensionPoints.CommandPalette,
title: 'Component title 0',
description: 'Component description 0',
component: () => <div />,
});

getPluginLinkExtensions() and usePluginLinkExtensions()​

Both the getPluginLinkExtensions() function and the usePluginLinkExtensions() React hook can be replaced with the usePluginLinks() React hook.

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

getPluginComponentExtensions() and usePluginComponentExtensions()​

You can replace both the getPluginComponentExtensions() function and the usePluginComponentExtensions() React hook with the usePluginComponents() React hook.

getPluginComponentExtensions
- const { extensions } = getPluginComponentExtensions({
+ const { components, isLoading } = usePluginComponents({
extensionPointId: 'grafana/user/profile/tab/v1',
limitPerPlugin: 2,
});
usePluginComponentExtensions
- const { extensions, isLoading } = usePluginComponentExtensions({
+ const { components, isLoading } = usePluginComponents({
extensionPointId: 'grafana/user/profile/tab/v1',
limitPerPlugin: 2,
});

getPluginExtensions() and usePluginExtensions()​

Replace the getPluginExtensions() function and the usePluginExtensions() React hook based on their usage:

  • For links: Follow the link extensions instructions.

  • For components: Follow the component extensions instructions.

  • For both links and components: Use both usePluginLinks and usePluginComponents.

PluginExtensionLinkConfig and PluginExtensionComponentConfig​

The types PluginExtensionLinkConfig and PluginExtensionComponentConfig have been removed from @grafana/data. Replace them with PluginExtensionAddedLinkConfig and PluginExtensionAddedComponentConfig, respectively.

GetPluginExtensionsOptions​

The GetPluginExtensionsOptions type has been removed from @grafana/runtime in favor of specific types that match their corresponding hook parameters.

Quick reference​

The following table summarizes the API changes with notes explaining the key differences:

Deprecated APIEquivalent APINotes
AppPlugin.configureExtensionLink()AppPlugin.addLink()extensionPointId parameter renamed to targets, accepts string or string[]
AppPlugin.configureExtensionComponent()AppPlugin.addComponent()extensionPointId parameter renamed to targets, accepts string or string[]
getPluginLinkExtensions()usePluginLinks()Returns { links, isLoading } instead of { extensions }
usePluginLinkExtensions()usePluginLinks()Returns { links, isLoading } instead of { extensions }
getPluginComponentExtensions()usePluginComponents()Returns { components, isLoading } instead of { extensions }
usePluginComponentExtensions()usePluginComponents()Returns { components, isLoading } instead of { extensions, isLoading }
getPluginExtensions()usePluginLinks() or usePluginComponents()Split into two separate hooks based on extension type (links or components)
usePluginExtensions()usePluginLinks() or usePluginComponents()Split into two separate hooks based on extension type (links or components)
PluginExtensionComponentConfigPluginExtensionAddedComponentConfigUpdated type definition for component configuration
PluginExtensionLinkConfigPluginExtensionAddedLinkConfigUpdated type definition for link configuration
GetPluginExtensionsOptionsUsePluginLinksOptions or UsePluginComponentsOptions or UsePluginFunctionsOptionsUpdated type definition for hook parameters