Skip to content

Commit 0b40406

Browse files
committed
fix: add ScenesProvider for i18n initialization
Initialize @grafana/i18n before rendering scenes components. Workaround for grafana/scenes#1322
1 parent 72c4529 commit 0b40406

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

src/components/ScenesProvider.tsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React, { type ReactNode, useEffect, useState } from 'react';
2+
import { initPluginTranslations } from '@grafana/i18n';
3+
import { Spinner } from '@grafana/ui';
4+
import pluginJson from 'plugin.json';
5+
6+
// Initialize i18n (workaround for scenes#1322)
7+
const i18nPromise = initPluginTranslations(pluginJson.id);
8+
let i18nReady = false;
9+
i18nPromise.then(() => {
10+
i18nReady = true;
11+
});
12+
13+
export function ScenesProvider({ children }: { children: ReactNode }) {
14+
const [ready, setReady] = useState(i18nReady);
15+
16+
useEffect(() => {
17+
i18nPromise.then(() => setReady(true));
18+
}, []);
19+
20+
if (!ready) {
21+
return <Spinner />;
22+
}
23+
24+
return children;
25+
}

src/routing/InitialisedRouter.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useLimits } from 'hooks/useLimits';
1212
import { QueryParamMap, useNavigation } from 'hooks/useNavigation';
1313
import { useURLSearchParams } from 'hooks/useURLSearchParams';
1414
import { SceneRedirecter } from 'components/SceneRedirecter';
15+
import { ScenesProvider } from 'components/ScenesProvider';
1516
import { AlertingPage } from 'page/AlertingPage';
1617
import { CheckList } from 'page/CheckList';
1718
import { ChooseCheckGroup } from 'page/ChooseCheckGroup';
@@ -62,7 +63,9 @@ export const InitialisedRouter = () => {
6263
path={AppRoutes.Home}
6364
element={
6465
canReadChecks ? (
65-
<SceneHomepage />
66+
<ScenesProvider>
67+
<SceneHomepage />
68+
</ScenesProvider>
6669
) : (
6770
<UnauthorizedPage permissions={['grafana-synthetic-monitoring-app.checks:read']} />
6871
)
@@ -76,7 +79,9 @@ export const InitialisedRouter = () => {
7679
index
7780
element={
7881
canReadChecks ? (
79-
<DashboardPage />
82+
<ScenesProvider>
83+
<DashboardPage />
84+
</ScenesProvider>
8085
) : (
8186
<UnauthorizedPage permissions={['grafana-synthetic-monitoring-app.checks:read']} />
8287
)

webpack.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ const config = async (env): Promise<Configuration> => {
8888
// See: https://grafana.com/blog/2025/01/22/react-19-is-coming-to-grafana-what-plugin-developers-need-to-know/
8989
// Requires Grafana >= 12.3.0
9090
externals: ['react/jsx-runtime', 'react/jsx-dev-runtime'],
91+
// Ensure all @grafana/i18n imports resolve to the same copy
92+
// Required for @grafana/scenes to use the i18n instance initialized by initPluginTranslations
93+
resolve: {
94+
alias: {
95+
// workaround to keep scenes from crashing when running in dev mode, can remove when https://github.com/grafana/scenes/issues/1322 is resolved.
96+
'@grafana/i18n': path.resolve(__dirname, 'node_modules/@grafana/i18n'),
97+
},
98+
},
9199
output: {
92100
asyncChunks: true,
93101
publicPath: `public/plugins/${pluginJson.id}/`,

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@
10901090
micro-memoize "^4.1.2"
10911091
react-i18next "^15.0.0"
10921092

1093-
"@grafana/i18n@12.3.2":
1093+
"@grafana/i18n@12.3.2", "@grafana/i18n@^12.2.0":
10941094
version "12.3.2"
10951095
resolved "https://registry.yarnpkg.com/@grafana/i18n/-/i18n-12.3.2.tgz#f4dbb9b5aae2550486e57b94a433729ccb37f728"
10961096
integrity sha512-1H/iVe52ipd4Vj3lFvMpH266tn8QibfTDEaDoNMHgR/TP68233035Z71Tgv1GZai72k3R4gEeSF+03pMAilaOg==

0 commit comments

Comments
 (0)