|
| 1 | +--- |
| 2 | +id: migrate-11_6_x-to-12_0_x |
| 3 | +title: 11.6.x to 12.0.x |
| 4 | +sidebar_position: 1 |
| 5 | +description: How to migrate plugins from Grafana version 11.6.x to 12.0.x. |
| 6 | +keywords: |
| 7 | + - grafana |
| 8 | + - plugins |
| 9 | + - plugin |
| 10 | + - upgrading |
| 11 | + - updating |
| 12 | + - migration |
| 13 | +--- |
| 14 | + |
| 15 | +# Migrate plugins from Grafana version 11.6.x to 12.0.x |
| 16 | + |
| 17 | +This guide helps you migrate plugins from Grafana version 11.6.x to 12.0.x. |
| 18 | + |
| 19 | +## Prerequisites |
| 20 | + |
| 21 | +Before starting the migration: |
| 22 | + |
| 23 | +- Back up your plugin code |
| 24 | +- Ensure your development environment is up to date |
| 25 | +- Familiarize yourself with [the reactive APIs](/how-to-guides/ui-extensions/) introduced in Grafana 11.4 |
| 26 | + |
| 27 | +## Deprecated UI extension APIs removal |
| 28 | + |
| 29 | +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: |
| 30 | + |
| 31 | +- `usePluginExtensions()` |
| 32 | +- `usePluginLinkExtensions()` |
| 33 | +- `usePluginComponentExtensions()` |
| 34 | +- `getPluginExtensions()` |
| 35 | +- `getPluginLinkExtensions()` |
| 36 | +- `getPluginComponentExtensions()` |
| 37 | +- `AppPlugin.configureExtensionLink()` |
| 38 | +- `AppPlugin.configureExtensionComponent()` |
| 39 | + |
| 40 | +Using any of these APIs in Grafana 12 will result in an error. Additionally, the TypeScript types `PluginExtensionLinkConfig` and `PluginExtensionComponentConfig` have been removed. |
| 41 | + |
| 42 | +:::info |
| 43 | +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](/how-to-guides/runtime-checks.md#example-conditionally-use-react-hooks). |
| 44 | +::: |
| 45 | + |
| 46 | +### AppPlugin.configureExtensionLink() |
| 47 | + |
| 48 | +Replace the `configureExtensionLink` method with the `addLink` method. Update the `extensionPointId` parameter to `targets`, which accepts either a `string` or `string[]`. |
| 49 | + |
| 50 | +```diff |
| 51 | +- new AppPlugin().configureExtensionLink({ |
| 52 | ++ new AppPlugin().addLink({ |
| 53 | +- extensionPointId: PluginExtensionPoints.DashboardPanelMenu, |
| 54 | ++ targets: PluginExtensionPoints.DashboardPanelMenu, |
| 55 | + title: 'Component title 0', |
| 56 | + description: 'Component description 0', |
| 57 | + component: () => <div />, |
| 58 | +}); |
| 59 | +``` |
| 60 | + |
| 61 | +### AppPlugin.configureExtensionComponent() |
| 62 | + |
| 63 | +Replace the `configureExtensionComponent` method with the `addComponent` method. Update the `extensionPointId` parameter to `targets`, which accepts either a `string` or `string[]`. |
| 64 | + |
| 65 | +```diff |
| 66 | +- new AppPlugin().configureExtensionComponent({ |
| 67 | ++ new AppPlugin().addComponent({ |
| 68 | +- extensionPointId: PluginExtensionPoints.CommandPalette, |
| 69 | ++ targets: PluginExtensionPoints.CommandPalette, |
| 70 | + title: 'Component title 0', |
| 71 | + description: 'Component description 0', |
| 72 | + component: () => <div />, |
| 73 | +}); |
| 74 | +``` |
| 75 | + |
| 76 | +### getPluginLinkExtensions() and usePluginLinkExtensions() |
| 77 | + |
| 78 | +Both the `getPluginLinkExtensions()` function and the `usePluginLinkExtensions()` React hook can be replaced with the `usePluginLinks()` React hook. |
| 79 | + |
| 80 | +```diff title="getPluginLinkExtensions" |
| 81 | +- const { extensions } = getPluginLinkExtensions({ |
| 82 | ++ const { links, isLoading } = usePluginLinks({ |
| 83 | + extensionPointId: 'grafana/dashboard/panel/menu/v1', |
| 84 | + limitPerPlugin: 2, |
| 85 | + context: { |
| 86 | + panelId: '...', |
| 87 | + }, |
| 88 | +}); |
| 89 | +``` |
| 90 | + |
| 91 | +```diff title="usePluginLinkExtensions" |
| 92 | +- const { extensions, isLoading } = usePluginLinkExtensions({ |
| 93 | ++ const { links, isLoading } = usePluginLinks({ |
| 94 | + extensionPointId: 'grafana/dashboard/panel/menu/v1', |
| 95 | + limitPerPlugin: 2, |
| 96 | + context: { |
| 97 | + panelId: '...', |
| 98 | + }, |
| 99 | +}); |
| 100 | +``` |
| 101 | + |
| 102 | +### getPluginComponentExtensions() and usePluginComponentExtensions() |
| 103 | + |
| 104 | +You can replace both the `getPluginComponentExtensions()` function and the `usePluginComponentExtensions()` React hook with the `usePluginComponents()` React hook. |
| 105 | + |
| 106 | +```diff title="getPluginComponentExtensions" |
| 107 | +- const { extensions } = getPluginComponentExtensions({ |
| 108 | ++ const { components, isLoading } = usePluginComponents({ |
| 109 | + extensionPointId: 'grafana/user/profile/tab/v1', |
| 110 | + limitPerPlugin: 2, |
| 111 | +}); |
| 112 | +``` |
| 113 | + |
| 114 | +```diff title="usePluginComponentExtensions" |
| 115 | +- const { extensions, isLoading } = usePluginComponentExtensions({ |
| 116 | ++ const { components, isLoading } = usePluginComponents({ |
| 117 | + extensionPointId: 'grafana/user/profile/tab/v1', |
| 118 | + limitPerPlugin: 2, |
| 119 | +}); |
| 120 | +``` |
| 121 | + |
| 122 | +### getPluginExtensions() and usePluginExtensions() |
| 123 | + |
| 124 | +Replace the `getPluginExtensions()` function and the `usePluginExtensions()` React hook based on their usage: |
| 125 | + |
| 126 | +- **For links:** Follow the [link extensions](https://github.com/grafana/plugin-tools/pull/1639/files#getpluginlinkextensions-and-usepluginlinkextensions) instructions. |
| 127 | + |
| 128 | +- **For components:** Follow the [component extensions](https://github.com/grafana/plugin-tools/pull/1639/files#getplugincomponentextensions-and-useplugincomponentextensions) instructions. |
| 129 | + |
| 130 | +- **For both links and components:** Use both `usePluginLinks` and `usePluginComponents`. |
| 131 | + |
| 132 | +### PluginExtensionLinkConfig and PluginExtensionComponentConfig |
| 133 | + |
| 134 | +The types `PluginExtensionLinkConfig` and `PluginExtensionComponentConfig` have been removed from `@grafana/data`.Replace them with `PluginExtensionAddedLinkConfig` and `PluginExtensionAddedComponentConfig`, respectively. |
| 135 | + |
| 136 | +## Quick reference |
| 137 | + |
| 138 | +The following table summarizes the API changes with notes explaining the key differences: |
| 139 | + |
| 140 | +| Deprecated API | Equivalent API | Notes | |
| 141 | +| ----------------------------------------- | --------------------------------------------- | --------------------------------------------------------------------------------- | |
| 142 | +| `AppPlugin.configureExtensionLink()` | `AppPlugin.addLink()` | `extensionPointId` parameter renamed to `targets`, accepts `string` or `string[]` | |
| 143 | +| `AppPlugin.configureExtensionComponent()` | `AppPlugin.addComponent()` | `extensionPointId` parameter renamed to `targets`, accepts `string` or `string[]` | |
| 144 | +| `getPluginLinkExtensions()` | `usePluginLinks()` | Returns `{ links, isLoading }` instead of `{ extensions }` | |
| 145 | +| `usePluginLinkExtensions()` | `usePluginLinks()` | Returns `{ links, isLoading }` instead of `{ extensions }` | |
| 146 | +| `getPluginComponentExtensions()` | `usePluginComponents()` | Returns `{ components, isLoading }` instead of `{ extensions }` | |
| 147 | +| `usePluginComponentExtensions()` | `usePluginComponents()` | Returns `{ components, isLoading }` instead of `{ extensions, isLoading }` | |
| 148 | +| `getPluginExtensions()` | `usePluginLinks()` or `usePluginComponents()` | Split into two separate hooks based on extension type (links or components) | |
| 149 | +| `usePluginExtensions()` | `usePluginLinks()` or `usePluginComponents()` | Split into two separate hooks based on extension type (links or components) | |
| 150 | +| `PluginExtensionComponentConfig` | `PluginExtensionAddedComponentConfig` | Updated type definition for component configuration | |
| 151 | +| `PluginExtensionLinkConfig` | `PluginExtensionAddedLinkConfig` | Updated type definition for link configuration | |
0 commit comments