Marking i18next as an external package

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 externalized i18next.

  • Not affected: Plugins that make no use of i18next or plugins that already treat i18next 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:

  1. If you support Grafana >= 10.2.x only
  • No immediate action required: Grafana will provide i18next for you.
  1. If you must keep supporting Grafana < 10.2.x
  • Keep bundling i18next in your plugin by customizing your webpack config so i18next 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 remove i18next 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 updating package.json scripts. See how in Extend the Webpack config.
1 Like