Summary (TL;DR)
To help enable official plugin translation support, starting from version 5.26.1
of @grafana/create-plugin
we will mark the i18next
NPM package as an external provided by Grafana runtime for plugins. Note that this will break plugins that both (a) depend on i18next
being bundled and (b) are being run in a Grafana server older than v10.2.x. As a workaround, bundle i18next
in those plugins by customizing your webpack config, as shown in the example below.
What changed
We are marking i18next
as an external dependency for plugins built with Grafana’s plugin tooling. This lets Grafana provide a single, compatible i18n runtime while plugin code uses the @grafana/i18n
helpers and i18next
APIs without bundling its own copy. This change is part of the plugin internationalization and localization effort.
Why we made this change
-
Centralizing
i18next
avoids multiple bundled copies and version conflicts between plugins and core Grafana. -
It enables easier, consistent translation support for plugins using Grafana’s
@grafana/i18n
approach. Read more about translating your plugin.
Who is affected
-
Affected: Plugins that use
i18next
(or expect it to be bundled at build time) and still declare compatibility with Grafana versions older than 10.2.x. Those plugins may fail to load on older Grafana instances because the runtime in those older versions does not provide the externalizedi18next
. -
Not affected: Plugins that make no use of
i18next
or plugins that already treati18next
as an external (i.e., rely on the Grafana runtime to provide it) and target Grafana versions that include the external.
Action required (for plugin authors)
Choose one of the following options depending on your compatibility target:
- If you support Grafana >= 10.2.x only
- No immediate action required: Grafana will provide i18next for you.
- If you must keep supporting Grafana < 10.2.x
- Keep bundling
i18next
in your plugin by customizing your webpack config soi18next
is not treated as an external. The plugin tooling docs show how to extend the webpack config; below is a minimal example you can copy into webpack.config.ts in your project root to removei18next
from externals. After adding the file, update your package.json scripts to use it.
// webpack.config.ts
import type { Configuration } from 'webpack';
import { merge } from 'webpack-merge';
import grafanaConfig, { Env } from './.config/webpack/webpack.config';
const config = async (env: Env): Promise<Configuration> => {
const baseConfig = await grafanaConfig(env);
// Ensure externals are an array and remove 'i18next' so it gets bundled.
const baseExternals = (baseConfig.externals || []) as string[];
const externals = baseExternals.filter((e) => e !== 'i18next');
return merge(baseConfig, { externals });
};
export default config;
- After adding the file, update build/dev scripts in your package.json to point at
./webpack.config.ts
(see the “Extend the Webpack config” docs).
More resources
- Learn how to enable plugin translations using the recommended
i18next/@grafana/i18n flow
. Read more in Translate your plugin. - Learn how to extend default configurations for adding a custom
webpack.config.ts
and updatingpackage.json
scripts. See how in Extend the Webpack config.