diff --git a/package.json b/package.json
index 7f5d40559..3b61fddec 100644
--- a/package.json
+++ b/package.json
@@ -32,11 +32,15 @@
"babel-polyfill": "^6.26.0",
"core-js": "^3.32.0",
"eventemitter2": "^6.4.5",
+ "i18next": "^23.5.1",
+ "i18next-browser-languagedetector": "^7.1.0",
"lodash": "^4.17.21",
- "prop-types": "^15.8.1"
+ "prop-types": "^15.8.1",
+ "react-i18next": "^13.2.2"
},
"devDependencies": {
"@babel/core": "^7.22.9",
+ "@types/react": "^18.2.25",
"ajv-pack": "^0.3.1",
"babel-cli": "^6.24.1",
"babel-core": "^6.26.3",
diff --git a/src/components/FormEdit.jsx b/src/components/FormEdit.jsx
index b52f3b4da..42815673c 100644
--- a/src/components/FormEdit.jsx
+++ b/src/components/FormEdit.jsx
@@ -4,6 +4,7 @@ import FormBuilder from './FormBuilder';
import _set from 'lodash/set';
import _cloneDeep from 'lodash/cloneDeep';
import _camelCase from 'lodash/camelCase';
+import {Trans, useTranslation} from 'react-i18next';
const reducer = (form, {type, value}) => {
const formCopy = _cloneDeep(form);
@@ -45,6 +46,33 @@ const FormEdit = (props) => {
ref,
} = props;
+ const {t, i18n} = useTranslation();
+ let language = undefined;
+ let i18nOption = undefined;
+ if (options) {
+ language = options.language;
+ i18nOption = options.i18n;
+ }
+ useEffect(() => {
+ if (i18nOption) {
+ for (const lang of Object.keys(i18nOption)) {
+ i18n.addResourceBundle(
+ lang,
+ 'translations',
+ i18nOption[lang],
+ true,
+ true
+ );
+ }
+ }
+ }, [i18nOption]);
+
+ useEffect(() => {
+ if (language) {
+ i18n.changeLanguage(language);
+ }
+ }, [language]);
+
const [form, dispatchFormAction] = useReducer(reducer, _cloneDeep(propsForm));
useEffect(() => {
const {form: newForm} = props;
@@ -73,11 +101,13 @@ const FormEdit = (props) => {
-
+
handleChange('title', event)}
/>
@@ -85,12 +115,14 @@ const FormEdit = (props) => {
-
+
handleChange('name', event)}
/>
@@ -98,7 +130,9 @@ const FormEdit = (props) => {
-
+
handleChange('path', event)}
diff --git a/src/i18n.js b/src/i18n.js
new file mode 100644
index 000000000..df6e7f793
--- /dev/null
+++ b/src/i18n.js
@@ -0,0 +1,23 @@
+import i18n from 'i18next';
+import LanguageDetector from 'i18next-browser-languagedetector';
+import {initReactI18next} from 'react-i18next';
+import englishTranslation from './translations/en';
+
+i18n
+ .use(LanguageDetector)
+ .use(initReactI18next)
+ .init({
+ resources: {
+ en: {
+ translations: englishTranslation
+ },
+ },
+ fallbackLng: 'en',
+ ns: 'translations',
+ keySeparator: false, // recommended when working with flat objects
+ interpolation: {
+ escapeValue: false
+ }
+ });
+
+export default i18n;
diff --git a/src/index.js b/src/index.js
index 3f736e825..8a42d4e14 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,4 +1,5 @@
import {Formio} from 'formiojs';
+import './i18n';
const Webform = Formio.Webform;
const WebformBuilder = Formio.WebformBuilder;
const Wizard = Formio.Wizard;
diff --git a/src/translations/en.js b/src/translations/en.js
new file mode 100644
index 000000000..ebdab0809
--- /dev/null
+++ b/src/translations/en.js
@@ -0,0 +1,14 @@
+export default {
+ Title: 'Title',
+ Name: 'Name',
+ 'Display as': 'Display as',
+ Type: 'Type',
+ Form: 'Form',
+ Resource: 'Resource',
+ Path: 'Path',
+ 'Enter the form title': 'Enter the form title',
+ Wizard: 'Wizard',
+ PDF: 'PDF',
+ 'Enter the form machine name': 'Enter the form machine name',
+ 'example': 'example'
+};
diff --git a/yarn.lock b/yarn.lock
index e3ae87d3b..ab45cad29 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -230,7 +230,7 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719"
integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==
-"@babel/runtime@^7.20.6", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.19.4", "@babel/runtime@^7.20.6", "@babel/runtime@^7.22.5", "@babel/runtime@^7.9.2":
version "7.23.1"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.1.tgz#72741dc4d413338a91dcb044a86f3c0bc402646d"
integrity sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==
@@ -513,6 +513,25 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.3.tgz#b31eb300610c3835ac008d690de6f87e28f9b878"
integrity sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==
+"@types/prop-types@*":
+ version "15.7.8"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.8.tgz#805eae6e8f41bd19e88917d2ea200dc992f405d3"
+ integrity sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==
+
+"@types/react@^18.2.25":
+ version "18.2.25"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.25.tgz#99fa44154132979e870ff409dc5b6e67f06f0199"
+ integrity sha512-24xqse6+VByVLIr+xWaQ9muX1B4bXJKXBbjszbld/UEDslGLY53+ZucF44HCmLbMPejTzGG9XgR+3m2/Wqu1kw==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
+"@types/scheduler@*":
+ version "0.16.4"
+ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.4.tgz#fedc3e5b15c26dc18faae96bf1317487cb3658cf"
+ integrity sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==
+
"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5":
version "1.11.6"
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24"
@@ -2297,6 +2316,11 @@ cssstyle@^3.0.0:
dependencies:
rrweb-cssom "^0.6.0"
+csstype@^3.0.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
+ integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
+
custom-event-polyfill@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz#9bc993ddda937c1a30ccd335614c6c58c4f87aee"
@@ -3826,6 +3850,13 @@ html-encoding-sniffer@^3.0.0:
dependencies:
whatwg-encoding "^2.0.0"
+html-parse-stringify@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2"
+ integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==
+ dependencies:
+ void-elements "3.1.0"
+
htmlparser2@^8.0.1:
version "8.0.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21"
@@ -3873,6 +3904,13 @@ https-proxy-agent@^5.0.1:
agent-base "6"
debug "4"
+i18next-browser-languagedetector@^7.1.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.1.0.tgz#01876fac51f86b78975e79b48ccb62e2313a2d7d"
+ integrity sha512-cr2k7u1XJJ4HTOjM9GyOMtbOA47RtUoWRAtt52z43r3AoMs2StYKyjS3URPhzHaf+mn10hY9dZWamga5WPQjhA==
+ dependencies:
+ "@babel/runtime" "^7.19.4"
+
i18next@22.4.12:
version "22.4.12"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.4.12.tgz#fde322c186501ea1adcdfac41b2d2552b26eab42"
@@ -3880,6 +3918,13 @@ i18next@22.4.12:
dependencies:
"@babel/runtime" "^7.20.6"
+i18next@^23.5.1:
+ version "23.5.1"
+ resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.5.1.tgz#7f7c35ffaa907618d9489f106d5006b09fbca3d3"
+ integrity sha512-JelYzcaCoFDaa+Ysbfz2JsGAKkrHiMG6S61+HLBUEIPaF40WMwW9hCPymlQGrP+wWawKxKPuSuD71WZscCsWHg==
+ dependencies:
+ "@babel/runtime" "^7.22.5"
+
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -5531,6 +5576,14 @@ react-dom@^18.1.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
+react-i18next@^13.2.2:
+ version "13.2.2"
+ resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-13.2.2.tgz#b1e78ed66a54f4bc819616f68b98221e1b1a1936"
+ integrity sha512-+nFUkbRByFwnrfDcYqvzBuaeZb+nACHx+fAWN/pZMddWOCJH5hoc21+Sa/N/Lqi6ne6/9wC/qRGOoQhJa6IkEQ==
+ dependencies:
+ "@babel/runtime" "^7.22.5"
+ html-parse-stringify "^3.0.1"
+
"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
@@ -6670,6 +6723,11 @@ vary@^1:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
+void-elements@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
+ integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==
+
void-elements@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"