diff --git a/src/i18n/i18n.ts b/src/i18n/i18n.ts
index e4f8067..efda870 100644
--- a/src/i18n/i18n.ts
+++ b/src/i18n/i18n.ts
@@ -18,11 +18,197 @@ const getLanguageFromURL = (): string => {
return "ru"; // Жёсткий фолбэк
};
+const r = {
+ ru: {
+ "quiz is inactive": "Квиз не активирован",
+ "no questions found": "Нет созданных вопросов",
+ "quiz is empty": "Квиз пуст",
+ "quiz already completed": "Вы уже прошли этот опрос",
+ "no quiz id": "Отсутствует id квиза",
+ "quiz data is null": "Не были переданы параметры квиза",
+ "invalid request data": "Такого квиза не существует",
+ "default message": "Что-то пошло не так",
+ "The request could not be sent": "Заявка не может быть отправлена",
+ "The number of points could not be sent": "Количество баллов не может быть отправлено",
+ "Your result": "Ваш результат",
+ "Your points": "Ваши баллы",
+ of: "из",
+ "View answers": "Посмотреть ответы",
+ "Find out more": "Узнать подробнее",
+ "Go to website": "Перейти на сайт",
+ "Question title": "Заголовок вопроса",
+ "Question without a title": "Вопрос без названия",
+ "Your answer": "Ваш ответ",
+ "Add image": "Добавить изображение",
+ "Accepts images": "Принимает изображения",
+ "Add video": "Добавить видео",
+ "Accepts .mp4 and .mov format - maximum 50mb": "Принимает .mp4 и .mov формат — максимум 50мб",
+ "Add audio file": "Добавить аудиофайл",
+ "Accepts audio files": "Принимает аудиофайлы",
+ "Add document": "Добавить документ",
+ "Accepts documents": "Принимает документы",
+ Next: "Далее",
+ Prev: "Назад",
+ From: "От",
+ До: "До",
+ "Enter your answer": "Введите свой ответ",
+ "Incorrect file type selected": "Выбран некорректный тип файла",
+ "File is too big. Maximum size is 50 MB": "Файл слишком большой. Максимальный размер 50 МБ",
+ "Acceptable file extensions": "Допустимые расширения файлов",
+ "You have uploaded": "Вы загрузили",
+ "The answer was not counted": "Ответ не был засчитан",
+ "Select an answer option below": "Выберите вариант ответа ниже",
+ "Select an answer option on the left": "Выберите вариант ответа слева",
+ "Fill out the form to receive your test results": "Заполните форму, чтобы получить результаты теста",
+ Enter: "Введите",
+ Name: "Имя",
+ "Phone number": "Номер телефона",
+ "Last name": "Фамилия",
+ Address: "Адрес",
+ "Incorrect email entered": "Введена некорректная почта",
+ "Please fill in the fields": "Пожалуйста, заполните поля",
+ "Please try again later": "повторите попытку позже",
+ "Regulation on the processing of personal data": "Положением об обработке персональных данных",
+ "Privacy Policy": "Политикой конфиденциальности",
+ familiarized: "ознакомлен",
+ and: "и",
+ "Get results": "Получить результаты",
+ "Data sent successfully": "Данные успешно отправлены",
+ Step: "Шаг",
+ "questions are not ready yet": "Вопросы для аудитории ещё не созданы. Пожалуйста, подождите",
+ "Add your image": "Добавьте своё изображение",
+ "select emoji": "выберите смайлик",
+ "file is too big": "Файл слишком большой",
+ "file type is not supported": "Тип файла не поддерживается",
+ },
+ en: {
+ "quiz is inactive": "Quiz is inactive",
+ "no questions found": "No questions found",
+ "quiz is empty": "Quiz is empty",
+ "quiz already completed": "You've already completed this quiz",
+ "no quiz id": "Missing quiz ID",
+ "quiz data is null": "No quiz parameters were provided",
+ "invalid request data": "This quiz doesn't exist",
+ "default message": "Something went wrong",
+ "The request could not be sent": "Request could not be sent",
+ "The number of points could not be sent": "Points could not be submitted",
+ "Your result": "Your result",
+ "Your points": "Your points",
+ of: "of",
+ "View answers": "View answers",
+ "Find out more": "Learn more",
+ "Go to website": "Go to website",
+ "Question title": "Question title",
+ "Question without a title": "Untitled question",
+ "Your answer": "Your answer",
+ "Add image": "Add image",
+ "Accepts images": "Accepts images",
+ "Add video": "Add video",
+ "Accepts .mp4 and .mov format - maximum 50mb": "Accepts .mp4 and .mov format - maximum 50MB",
+ "Add audio file": "Add audio file",
+ "Accepts audio files": "Accepts audio files",
+ "Add document": "Add document",
+ "Accepts documents": "Accepts documents",
+ Next: "Next",
+ Prev: "Previous",
+ From: "From",
+ До: "To",
+ "Enter your answer": "Enter your answer",
+ "Incorrect file type selected": "Invalid file type selected",
+ "File is too big. Maximum size is 50 MB": "File is too large. Maximum size is 50 MB",
+ "Acceptable file extensions": "Allowed file extensions",
+ "You have uploaded": "You've uploaded",
+ "The answer was not counted": "Answer wasn't counted",
+ "Select an answer option below": "Select an answer option below",
+ "Select an answer option on the left": "Select an answer option on the left",
+ "Fill out the form to receive your test results": "Fill out the form to receive your test results",
+ Enter: "Enter",
+ Name: "Name",
+ "Phone number": "Phone number",
+ "Last name": "Last name",
+ Address: "Address",
+ "Incorrect email entered": "Invalid email entered",
+ "Please fill in the fields": "Please fill in the fields",
+ "Please try again later": "Please try again later",
+ "Regulation on the processing of personal data": "Personal Data Processing Regulation",
+ "Privacy Policy": "Privacy Policy",
+ familiarized: "acknowledged",
+ and: "and",
+ "Get results": "Get results",
+ "Data sent successfully": "Data sent successfully",
+ Step: "Step",
+ "questions are not ready yet": "There are no questions for the audience yet. Please wait",
+ "Add your image": "Add your image",
+ "select emoji": "select emoji",
+ },
+ uz: {
+ "quiz is inactive": "Test faol emas",
+ "no questions found": "Savollar topilmadi",
+ "quiz is empty": "Test boʻsh",
+ "quiz already completed": "Siz bu testni allaqachon topshirgansiz",
+ "no quiz id": "Test IDsi yoʻq",
+ "quiz data is null": "Test parametrlari yuborilmagan",
+ "invalid request data": "Bunday test mavjud emas",
+ "default message": "Xatolik yuz berdi",
+ "The request could not be sent": "Soʻrov yuborib boʻlmadi",
+ "The number of points could not be sent": "Ballar yuborib boʻlmadi",
+ "Your result": "Sizning natijangiz",
+ "Your points": "Sizning ballaringiz",
+ of: "/",
+ "View answers": "Javoblarni koʻrish",
+ "Find out more": "Batafsil maʼlumot",
+ "Go to website": "Veb-saytga oʻtish",
+ "Question title": "Savol sarlavhasi",
+ "Question without a title": "Sarlavhasiz savol",
+ "Your answer": "Sizning javobingiz",
+ "Add image": "Rasm qoʻshish",
+ "Accepts images": "Rasmlarni qabul qiladi",
+ "Add video": "Video qoʻshish",
+ "Accepts .mp4 and .mov format - maximum 50mb": ".mp4 va .mov formatlarini qabul qiladi - maksimal 50MB",
+ "Add audio file": "Audio fayl qoʻshish",
+ "Accepts audio files": "Audio fayllarni qabul qiladi",
+ "Add document": "Hujjat qoʻshish",
+ "Accepts documents": "Hujjatlarni qabul qiladi",
+ Next: "Keyingi",
+ Prev: "Oldingi",
+ From: "Dan",
+ До: "Gacha",
+ "Enter your answer": "Javobingizni kiriting",
+ "Incorrect file type selected": "Notoʻgʻri fayl turi tanlandi",
+ "File is too big. Maximum size is 50 MB": "Fayl juda katta. Maksimal hajmi 50 MB",
+ "Acceptable file extensions": "Qabul qilinadigan fayl kengaytmalari",
+ "You have uploaded": "Siz yuklagansiz",
+ "The answer was not counted": "Javob hisobga olinmadi",
+ "Select an answer option below": "Quyidagi javob variantlaridan birini tanlang",
+ "Select an answer option on the left": "Chapdagi javob variantlaridan birini tanlang",
+ "Fill out the form to receive your test results": "Test natijalaringizni olish uchun shaklni toʻldiring",
+ Enter: "Kiriting",
+ Name: "Ism",
+ "Phone number": "Telefon raqami",
+ "Last name": "Familiya",
+ Address: "Manzil",
+ "Incorrect email entered": "Notoʻgʻri elektron pochta kiritildi",
+ "Please fill in the fields": "Iltimos, maydonlarni toʻldiring",
+ "Please try again later": "Iltimos, keyinroq urinib koʻring",
+ "Regulation on the processing of personal data": "Shaxsiy maʼlumotlarni qayta ishlash qoidalari",
+ "Privacy Policy": "Maxfiylik siyosati",
+ familiarized: "tanishdim",
+ and: "va",
+ "Get results": "Natijalarni olish",
+ "Data sent successfully": "Ma'lumotlar muvaffaqiyatli yuborildi",
+ Step: "Qadam",
+ "questions are not ready yet": "Tomoshabinlar uchun hozircha savollar yo'q. Iltimos kuting",
+ "Add your image": "Rasmingizni qo'shing",
+ "select emoji": "emoji tanlang",
+ },
+};
+
// 2. Конфиг с полной отладкой
i18n
.use(Backend)
.use(initReactI18next)
.init({
+ resources: r,
lng: getLanguageFromURL(), // Принудительно из URL
fallbackLng: "ru",
supportedLngs: ["en", "ru", "uz"],
diff --git a/src/i18n/i18nWidget.ts b/src/i18n/i18nWidget.ts
new file mode 100644
index 0000000..693e57a
--- /dev/null
+++ b/src/i18n/i18nWidget.ts
@@ -0,0 +1,240 @@
+import i18n from "i18next";
+import { initReactI18next } from "react-i18next";
+
+// 1. Функция для определения языка из URL
+const getLanguageFromURL = (): string => {
+ const path = window.location.pathname;
+ const langMatch = path.match(/^\/(en|ru|uz)(\/|$)/i);
+ return langMatch ? langMatch[1].toLowerCase() : "ru"; // Фолбэк на 'ru'
+};
+
+// 2. Локали, встроенные прямо в конфиг
+
+const r = {
+ ru: {
+ "quiz is inactive": "Квиз не активирован",
+ "no questions found": "Нет созданных вопросов",
+ "quiz is empty": "Квиз пуст",
+ "quiz already completed": "Вы уже прошли этот опрос",
+ "no quiz id": "Отсутствует id квиза",
+ "quiz data is null": "Не были переданы параметры квиза",
+ "invalid request data": "Такого квиза не существует",
+ "default message": "Что-то пошло не так",
+ "The request could not be sent": "Заявка не может быть отправлена",
+ "The number of points could not be sent": "Количество баллов не может быть отправлено",
+ "Your result": "Ваш результат",
+ "Your points": "Ваши баллы",
+ of: "из",
+ "View answers": "Посмотреть ответы",
+ "Find out more": "Узнать подробнее",
+ "Go to website": "Перейти на сайт",
+ "Question title": "Заголовок вопроса",
+ "Question without a title": "Вопрос без названия",
+ "Your answer": "Ваш ответ",
+ "Add image": "Добавить изображение",
+ "Accepts images": "Принимает изображения",
+ "Add video": "Добавить видео",
+ "Accepts .mp4 and .mov format - maximum 50mb": "Принимает .mp4 и .mov формат — максимум 50мб",
+ "Add audio file": "Добавить аудиофайл",
+ "Accepts audio files": "Принимает аудиофайлы",
+ "Add document": "Добавить документ",
+ "Accepts documents": "Принимает документы",
+ Next: "Далее",
+ Prev: "Назад",
+ From: "От",
+ До: "До",
+ "Enter your answer": "Введите свой ответ",
+ "Incorrect file type selected": "Выбран некорректный тип файла",
+ "File is too big. Maximum size is 50 MB": "Файл слишком большой. Максимальный размер 50 МБ",
+ "Acceptable file extensions": "Допустимые расширения файлов",
+ "You have uploaded": "Вы загрузили",
+ "The answer was not counted": "Ответ не был засчитан",
+ "Select an answer option below": "Выберите вариант ответа ниже",
+ "Select an answer option on the left": "Выберите вариант ответа слева",
+ "Fill out the form to receive your test results": "Заполните форму, чтобы получить результаты теста",
+ Enter: "Введите",
+ Name: "Имя",
+ "Phone number": "Номер телефона",
+ "Last name": "Фамилия",
+ Address: "Адрес",
+ "Incorrect email entered": "Введена некорректная почта",
+ "Please fill in the fields": "Пожалуйста, заполните поля",
+ "Please try again later": "повторите попытку позже",
+ "Regulation on the processing of personal data": "Положением об обработке персональных данных",
+ "Privacy Policy": "Политикой конфиденциальности",
+ familiarized: "ознакомлен",
+ and: "и",
+ "Get results": "Получить результаты",
+ "Data sent successfully": "Данные успешно отправлены",
+ Step: "Шаг",
+ "questions are not ready yet": "Вопросы для аудитории ещё не созданы. Пожалуйста, подождите",
+ "Add your image": "Добавьте своё изображение",
+ "select emoji": "выберите смайлик",
+ "file is too big": "Файл слишком большой",
+ "file type is not supported": "Тип файла не поддерживается",
+ },
+ en: {
+ "quiz is inactive": "Quiz is inactive",
+ "no questions found": "No questions found",
+ "quiz is empty": "Quiz is empty",
+ "quiz already completed": "You've already completed this quiz",
+ "no quiz id": "Missing quiz ID",
+ "quiz data is null": "No quiz parameters were provided",
+ "invalid request data": "This quiz doesn't exist",
+ "default message": "Something went wrong",
+ "The request could not be sent": "Request could not be sent",
+ "The number of points could not be sent": "Points could not be submitted",
+ "Your result": "Your result",
+ "Your points": "Your points",
+ of: "of",
+ "View answers": "View answers",
+ "Find out more": "Learn more",
+ "Go to website": "Go to website",
+ "Question title": "Question title",
+ "Question without a title": "Untitled question",
+ "Your answer": "Your answer",
+ "Add image": "Add image",
+ "Accepts images": "Accepts images",
+ "Add video": "Add video",
+ "Accepts .mp4 and .mov format - maximum 50mb": "Accepts .mp4 and .mov format - maximum 50MB",
+ "Add audio file": "Add audio file",
+ "Accepts audio files": "Accepts audio files",
+ "Add document": "Add document",
+ "Accepts documents": "Accepts documents",
+ Next: "Next",
+ Prev: "Previous",
+ From: "From",
+ До: "To",
+ "Enter your answer": "Enter your answer",
+ "Incorrect file type selected": "Invalid file type selected",
+ "File is too big. Maximum size is 50 MB": "File is too large. Maximum size is 50 MB",
+ "Acceptable file extensions": "Allowed file extensions",
+ "You have uploaded": "You've uploaded",
+ "The answer was not counted": "Answer wasn't counted",
+ "Select an answer option below": "Select an answer option below",
+ "Select an answer option on the left": "Select an answer option on the left",
+ "Fill out the form to receive your test results": "Fill out the form to receive your test results",
+ Enter: "Enter",
+ Name: "Name",
+ "Phone number": "Phone number",
+ "Last name": "Last name",
+ Address: "Address",
+ "Incorrect email entered": "Invalid email entered",
+ "Please fill in the fields": "Please fill in the fields",
+ "Please try again later": "Please try again later",
+ "Regulation on the processing of personal data": "Personal Data Processing Regulation",
+ "Privacy Policy": "Privacy Policy",
+ familiarized: "acknowledged",
+ and: "and",
+ "Get results": "Get results",
+ "Data sent successfully": "Data sent successfully",
+ Step: "Step",
+ "questions are not ready yet": "There are no questions for the audience yet. Please wait",
+ "Add your image": "Add your image",
+ "select emoji": "select emoji",
+ },
+ uz: {
+ "quiz is inactive": "Test faol emas",
+ "no questions found": "Savollar topilmadi",
+ "quiz is empty": "Test boʻsh",
+ "quiz already completed": "Siz bu testni allaqachon topshirgansiz",
+ "no quiz id": "Test IDsi yoʻq",
+ "quiz data is null": "Test parametrlari yuborilmagan",
+ "invalid request data": "Bunday test mavjud emas",
+ "default message": "Xatolik yuz berdi",
+ "The request could not be sent": "Soʻrov yuborib boʻlmadi",
+ "The number of points could not be sent": "Ballar yuborib boʻlmadi",
+ "Your result": "Sizning natijangiz",
+ "Your points": "Sizning ballaringiz",
+ of: "/",
+ "View answers": "Javoblarni koʻrish",
+ "Find out more": "Batafsil maʼlumot",
+ "Go to website": "Veb-saytga oʻtish",
+ "Question title": "Savol sarlavhasi",
+ "Question without a title": "Sarlavhasiz savol",
+ "Your answer": "Sizning javobingiz",
+ "Add image": "Rasm qoʻshish",
+ "Accepts images": "Rasmlarni qabul qiladi",
+ "Add video": "Video qoʻshish",
+ "Accepts .mp4 and .mov format - maximum 50mb": ".mp4 va .mov formatlarini qabul qiladi - maksimal 50MB",
+ "Add audio file": "Audio fayl qoʻshish",
+ "Accepts audio files": "Audio fayllarni qabul qiladi",
+ "Add document": "Hujjat qoʻshish",
+ "Accepts documents": "Hujjatlarni qabul qiladi",
+ Next: "Keyingi",
+ Prev: "Oldingi",
+ From: "Dan",
+ До: "Gacha",
+ "Enter your answer": "Javobingizni kiriting",
+ "Incorrect file type selected": "Notoʻgʻri fayl turi tanlandi",
+ "File is too big. Maximum size is 50 MB": "Fayl juda katta. Maksimal hajmi 50 MB",
+ "Acceptable file extensions": "Qabul qilinadigan fayl kengaytmalari",
+ "You have uploaded": "Siz yuklagansiz",
+ "The answer was not counted": "Javob hisobga olinmadi",
+ "Select an answer option below": "Quyidagi javob variantlaridan birini tanlang",
+ "Select an answer option on the left": "Chapdagi javob variantlaridan birini tanlang",
+ "Fill out the form to receive your test results": "Test natijalaringizni olish uchun shaklni toʻldiring",
+ Enter: "Kiriting",
+ Name: "Ism",
+ "Phone number": "Telefon raqami",
+ "Last name": "Familiya",
+ Address: "Manzil",
+ "Incorrect email entered": "Notoʻgʻri elektron pochta kiritildi",
+ "Please fill in the fields": "Iltimos, maydonlarni toʻldiring",
+ "Please try again later": "Iltimos, keyinroq urinib koʻring",
+ "Regulation on the processing of personal data": "Shaxsiy maʼlumotlarni qayta ishlash qoidalari",
+ "Privacy Policy": "Maxfiylik siyosati",
+ familiarized: "tanishdim",
+ and: "va",
+ "Get results": "Natijalarni olish",
+ "Data sent successfully": "Ma'lumotlar muvaffaqiyatli yuborildi",
+ Step: "Qadam",
+ "questions are not ready yet": "Tomoshabinlar uchun hozircha savollar yo'q. Iltimos kuting",
+ "Add your image": "Rasmingizni qo'shing",
+ "select emoji": "emoji tanlang",
+ },
+};
+
+// 3. Конфигурация i18n без Backend
+i18n
+ .use(initReactI18next)
+ .init({
+ resources: r, // Используем встроенные переводы
+ lng: getLanguageFromURL(),
+ fallbackLng: "ru",
+ supportedLngs: ["en", "ru", "uz"],
+ debug: true,
+ interpolation: {
+ escapeValue: false,
+ },
+ react: {
+ useSuspense: false,
+ },
+ detection: {
+ order: ["path"],
+ lookupFromPathIndex: 0,
+ caches: [],
+ },
+ parseMissingKeyHandler: (key) => {
+ console.warn("Missing translation:", key);
+ return key;
+ },
+ missingKeyHandler: (lngs, ns, key) => {
+ console.error("🚨 Missing i18n key:", {
+ key,
+ languages: lngs,
+ namespace: ns,
+ stack: new Error().stack,
+ });
+ },
+ })
+ .then(() => {
+ console.log("i18n initialized. Current language:", i18n.language);
+ });
+
+// 4. Логирование событий
+i18n.on("languageChanged", (lng) => {
+ console.log("Language changed to:", lng);
+});
+
+export default i18n;
diff --git a/src/widget.tsx b/src/widget.tsx
index 653e35b..97c62d8 100644
--- a/src/widget.tsx
+++ b/src/widget.tsx
@@ -2,6 +2,7 @@ import QuizAnswerer from "@/components/QuizAnswerer";
import { createRoot } from "react-dom/client";
// eslint-disable-next-line react-refresh/only-export-components
export * from "./widgets";
+import "./i18n/i18nWidget";
// old widget
const widget = {
@@ -19,7 +20,13 @@ const widget = {
const root = createRoot(element);
- root.render();
+ root.render(
+
+ );
},
};