Skip to content

Commit 6599ff6

Browse files
authored
Dynamically set i18n resources for Storybook and tests (#68)
## Changes - Remove the `resources` option from Storybook's i18next initialization. We're utilizing the `i18next-http-backend` package for loading locales in Storybook via HTTP requests, so manually setting them doesn't appear to be required for it to render the strings. - Update Jest's i18next initialization to dynamically set `resources` based on the file structure. This removes the need for updating the Jest setup file every time a new language file is created. - Fix the `test-update` script
1 parent 3be3e52 commit 6599ff6

File tree

3 files changed

+48
-34
lines changed

3 files changed

+48
-34
lines changed

app/.storybook/i18next.js

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Configure i18next for storybook addon storybook-react-i18next
1+
// Configure i18next for Storybook
22
// See https://storybook.js.org/addons/storybook-react-i18next
33
import i18next from "i18next";
44
import LanguageDetector from "i18next-browser-languagedetector";
@@ -7,27 +7,10 @@ import { initReactI18next } from "react-i18next";
77

88
import i18nConfig from "../next-i18next.config";
99

10-
const { i18n, ...i18nextOptions } = i18nConfig;
11-
const ns = ["common"];
12-
13-
const resources = ns.reduce((acc, n) => {
14-
i18n.locales.forEach((lng) => {
15-
if (!acc[lng]) acc[lng] = {};
16-
acc[lng] = {
17-
...acc[lng],
18-
[n]: require(`../public/locales/${lng}/${n}.json`),
19-
};
20-
});
21-
return acc;
22-
}, {});
23-
2410
i18next
2511
.use(initReactI18next)
2612
.use(LanguageDetector)
2713
.use(Backend)
28-
.init({
29-
...i18nextOptions,
30-
resources,
31-
});
14+
.init(i18nConfig);
3215

3316
export default i18next;

app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"storybook": "start-storybook -p 6006",
1515
"storybook-build": "build-storybook",
1616
"test": "jest --ci --coverage",
17-
"test-update": "jest --update-snapshots",
17+
"test-update": "jest --update-snapshot",
1818
"test-watch": "jest --watch",
1919
"ts:check": "tsc --noEmit"
2020
},

app/tests/jest-i18n.ts

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,52 @@
1-
import i18n from "i18next";
1+
/**
2+
* @file Setup internationalization for tests so snapshots and queries reference the correct translations
3+
*/
4+
import fs from "fs";
5+
import i18n, { InitOptions } from "i18next";
6+
import path from "path";
27
import { initReactI18next } from "react-i18next";
38

49
// @ts-expect-error - Config file has to be .js
510
import i18nConfig from "../next-i18next.config";
6-
import enCommon from "../public/locales/en/common.json";
7-
import esCommon from "../public/locales/es/common.json";
8-
9-
// Setup internationalization for tests so snapshots and queries reference the correct translations
10-
i18n.use(initReactI18next).init({
11-
...i18nConfig,
12-
resources: {
13-
en: {
14-
common: enCommon,
15-
},
16-
es: { common: esCommon },
17-
},
18-
});
11+
12+
const locales = i18nConfig.i18n.locales;
13+
14+
/**
15+
* Load all of the locales into a single object. A server isn't running for our tests,
16+
* so we can't load these static assets using HTTP requests like in Storybook.
17+
* https://www.i18next.com/how-to/add-or-load-translations
18+
*/
19+
export const getResources = () => {
20+
const resources: InitOptions["resources"] = {};
21+
22+
locales.forEach((locale: string) => {
23+
resources[locale] = {};
24+
25+
const namespaces = fs
26+
.readdirSync(path.resolve(__dirname, `../public/locales/${locale}`))
27+
.map((file) => file.replace(/\.json$/, ""));
28+
29+
namespaces.forEach((namespace) => {
30+
const namespacePath = `../public/locales/${locale}/${namespace}`;
31+
// eslint-disable-next-line
32+
resources[locale][namespace] = require(namespacePath);
33+
});
34+
35+
return resources;
36+
});
37+
38+
return resources;
39+
};
40+
41+
i18n
42+
.use(initReactI18next)
43+
.init({
44+
...i18nConfig,
45+
resources: getResources(),
46+
})
47+
.catch((err) => {
48+
throw err;
49+
});
1950

2051
// Export i18n so tests can manually set the language with:
2152
// i18n.changeLanguage('es')

0 commit comments

Comments
 (0)