Skip to content

Commit

Permalink
Merge pull request #188 from aruznieto/i18n
Browse files Browse the repository at this point in the history
feat: i18n - dynamic import on build time
  • Loading branch information
dec0dOS authored May 1, 2024
2 parents 6f7bc6c + d826cda commit 0fb9264
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 14 deletions.
3 changes: 2 additions & 1 deletion frontend/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,6 @@
"optional": "Optional",
"destination": "Destination",
"username": "Username",
"password": "Password"
"password": "Password",
"languageName": "English"
}
3 changes: 2 additions & 1 deletion frontend/public/locales/es-ES/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,6 @@
"optional": "Opcional",
"destination": "Destino",
"username": "Nombre de usuario",
"password": "Contraseña"
"password": "Contraseña",
"languageName": "Español"
}
14 changes: 6 additions & 8 deletions frontend/src/components/Settings/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@ import {
Accordion,
AccordionSummary,
AccordionDetails,
Checkbox,
Divider,
Grid,
Typography,
TextField,
Select,
} from "@material-ui/core";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";

import API from "utils/API";
import { parseValue, replaceValue, setValue } from "utils/ChangeHelper";

import { useTranslation } from "react-i18next";
import localesList from "generated/localesList.json";

function Settings() {
const { t, i18n } = useTranslation();
Expand All @@ -31,8 +26,11 @@ function Settings() {
<AccordionDetails>
<Grid item>
<Select native value={i18n.language} onChange={handleChange()}>
<option value={"en"}>English</option>
<option value={"es-ES"}>Español</option>
{localesList.map((locale) => (
<option key={locale.code} value={locale.code}>
{locale.name}
</option>
))}
</Select>
</Grid>
</AccordionDetails>
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/generated/localesList.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"code": "en",
"name": "English"
},
{
"code": "es-ES",
"name": "Español"
}
]
5 changes: 3 additions & 2 deletions frontend/src/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import languageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
import Backend from "i18next-http-backend";

const userLanguage = window.navigator.language;
import localesList from "./utils/localesList.json";
const supportedLngs = localesList.map((locale) => locale.code);

i18n
.use(languageDetector)
Expand All @@ -23,7 +24,7 @@ i18n
react: {
useSuspense: true,
},
supportedLngs: ["en", "es-ES"],
supportedLngs,
backend: {
loadPath: "/locales/{{lng}}/{{ns}}.json",
},
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/utils/localesList.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"code": "en",
"name": "English"
},
{
"code": "es-ES",
"name": "Español"
}
]
3 changes: 2 additions & 1 deletion frontend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"baseUrl": "src",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"jsx": "preserve"
"jsx": "preserve",
"resolveJsonModule": true
},
"include": ["src"]
}
51 changes: 51 additions & 0 deletions frontend/vite-plugin-generate-locales.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import fs from "fs";
import path from "path";
import * as url from "url";

const __dirname = url.fileURLToPath(new URL(".", import.meta.url));

export default function GenerateLocalesPlugin() {
return {
name: "generate-locales",
buildStart() {
const localesDir = path.resolve(__dirname, "public", "locales");

if (fs.existsSync(localesDir)) {
const localesList = fs
.readdirSync(localesDir)
.filter((file) => {
return fs.statSync(path.join(localesDir, file)).isDirectory();
})
.map((locale) => {
const commonFilePath = path.join(localesDir, locale, "common.json");
if (fs.existsSync(commonFilePath)) {
const commonFile = JSON.parse(
fs.readFileSync(commonFilePath, "utf-8")
);
return {
code: locale,
name: commonFile.languageName || locale,
};
}
return {
code: locale,
name: locale,
};
});

// Save the array to a JSON file
const outputPath = path.resolve(
__dirname,
"src",
"generated",
"localesList.json"
);
fs.writeFileSync(outputPath, JSON.stringify(localesList, null, 2));

console.log(`Locales list saved to ${outputPath}`);
} else {
console.error("Locales directory not found.");
}
},
};
}
4 changes: 3 additions & 1 deletion frontend/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import process from "node:process";
import { defineConfig, searchForWorkspaceRoot } from "vite";
import react from "@vitejs/plugin-react";
import GenerateLocalesPlugin from "./vite-plugin-generate-locales.js";

export default defineConfig({
base: "/app",
Expand All @@ -21,11 +22,12 @@ export default defineConfig({
components: "/src/components",
utils: "/src/utils",
external: "/src/external",
generated: "/src/generated",
},
},
build: {
outDir: "build",
chunkSizeWarningLimit: 1000,
},
plugins: [react()],
plugins: [react(), GenerateLocalesPlugin()],
});

0 comments on commit 0fb9264

Please sign in to comment.