diff --git a/public/index.html b/public/index.html
index c2f391e53..c299d9223 100644
--- a/public/index.html
+++ b/public/index.html
@@ -751,7 +751,7 @@
                                     <div data-newbie-hidden class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
                                         <small>
                                             <span data-i18n="Top K">Top K</span>
-                                            <div class="fa-solid fa-circle-info opacity50p" title="Top K sets a maximum amount of top tokens that can be chosen from.&#13;E.g Top K is 20, this means only the 20 highest ranking tokens will be kept (regardless of their probabilities being diverse or limited).&#13;Set to 0 to disable."></div>
+                                            <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Top K sets a maximum amount of top tokens that can be chosen from" title="Top K sets a maximum amount of top tokens that can be chosen from.&#13;E.g Top K is 20, this means only the 20 highest ranking tokens will be kept (regardless of their probabilities being diverse or limited).&#13;Set to 0 to disable."></div>
                                         </small>
                                         <input class="neo-range-slider" type="range" id="top_k" name="volume" min="0" max="100" step="1">
                                         <input class="neo-range-input" type="number" min="0" max="100" step="1" data-for="top_k" id="top_k_counter">
@@ -759,7 +759,7 @@
                                     <div data-newbie-hidden class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
                                         <small>
                                             Top P
-                                            <div class="fa-solid fa-circle-info opacity50p" title="Top P (a.k.a. nucleus sampling) adds up all the top tokens required to add up to the target percentage.&#13;E.g If the Top 2 tokens are both 25%, and Top P is 0.50, only the Top 2 tokens are considered.&#13;Set to 1.0 to disable."></div>
+                                            <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Top P (a.k.a. nucleus sampling)" title="Top P (a.k.a. nucleus sampling) adds up all the top tokens required to add up to the target percentage.&#13;E.g If the Top 2 tokens are both 25%, and Top P is 0.50, only the Top 2 tokens are considered.&#13;Set to 1.0 to disable."></div>
                                         </small>
                                         <input class="neo-range-slider" type="range" id="top_p" name="volume" min="0" max="1" step="0.01">
                                         <input class="neo-range-input" type="number" min="0" max="1" step="0.01" data-for="top_p" id="top_p_counter">
@@ -767,7 +767,7 @@
                                     <div data-newbie-hidden class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
                                         <small>
                                             <span data-i18n="Typical P">Typical P</span>
-                                            <div class="fa-solid fa-circle-info opacity50p" title="Typical P Sampling prioritizes tokens based on their deviation from the average entropy of the set.&#13;It maintains tokens whose cumulative probability is close to a predefined threshold (e.g., 0.5), emphasizing those with average information content.&#13;Set to 1.0 to disable."></div>
+                                            <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Typical P Sampling prioritizes tokens based on their deviation from the average entropy of the set" title="Typical P Sampling prioritizes tokens based on their deviation from the average entropy of the set.&#13;It maintains tokens whose cumulative probability is close to a predefined threshold (e.g., 0.5), emphasizing those with average information content.&#13;Set to 1.0 to disable."></div>
                                         </small>
                                         <input class="neo-range-slider" type="range" id="typical_p" name="volume" min="0" max="1" step="0.001">
                                         <input class="neo-range-input" type="number" min="0" max="1" step="0.001" data-for="typical_p" id="typical_p_counter">
@@ -775,7 +775,7 @@
                                     <div class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
                                         <small>
                                             <span data-i18n="Min P">Min P</span>
-                                            <div class="fa-solid fa-circle-info opacity50p" title="Min P sets a base minimum probability.&#13;This is scaled according to the top token's probability.&#13;E.g If Top token is 80% probability, and Min P is 0.1, only tokens higher than 8% would be considered.&#13;Set to 0 to disable."></div>
+                                            <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Min P sets a base minimum probability" title="Min P sets a base minimum probability.&#13;This is scaled according to the top token's probability.&#13;E.g If Top token is 80% probability, and Min P is 0.1, only tokens higher than 8% would be considered.&#13;Set to 0 to disable."></div>
                                         </small>
                                         <input class="neo-range-slider" type="range" id="min_p" name="volume" min="0" max="1" step="0.001">
                                         <input class="neo-range-input" type="number" min="0" max="1" step="0.001" data-for="min_p" id="min_p_counter">
@@ -783,7 +783,7 @@
                                     <div data-newbie-hidden class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
                                         <small>
                                             <span data-i18n="Top A">Top A</span>
-                                            <div class="fa-solid fa-circle-info opacity50p" title="Top A sets a threshold for token selection based on the square of the highest token probability.&#13;E.g if the Top-A value is 0.2 and the top token's probability is 50%, tokens with probabilities below 5% (0.2 * 0.5^2) are excluded.&#13;Set to 0 to disable."></div>
+                                            <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Top A sets a threshold for token selection based on the square of the highest token probability" title="Top A sets a threshold for token selection based on the square of the highest token probability.&#13;E.g if the Top-A value is 0.2 and the top token's probability is 50%, tokens with probabilities below 5% (0.2 * 0.5^2) are excluded.&#13;Set to 0 to disable."></div>
                                         </small>
                                         <input class="neo-range-slider" type="range" id="top_a" name="volume" min="0" max="1" step="0.001">
                                         <input class="neo-range-input" type="number" min="0" max="1" step="0.001" data-for="top_a" id="top_a_counter">
@@ -791,7 +791,7 @@
                                     <div data-newbie-hidden class="alignitemscenter flex-container flexFlowColumn flexBasis30p flexGrow flexShrink gap0">
                                         <small>
                                             <span data-i18n="Tail Free Sampling">TFS</span>
-                                            <div class="fa-solid fa-circle-info opacity50p" title="Tail-Free Sampling (TFS) searches for a tail of low-probability tokens in the distribution,&#13;by analyzing the rate of change in token probabilities using derivatives. It retains tokens up to a threshold (e.g., 0.3) based on the normalized second derivative.&#13;The closer to 0, the more discarded tokens. Set to 1.0 to disable."></div>
+                                            <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]Tail-Free Sampling (TFS)" title="Tail-Free Sampling (TFS) searches for a tail of low-probability tokens in the distribution,&#13;by analyzing the rate of change in token probabilities using derivatives. It retains tokens up to a threshold (e.g., 0.3) based on the normalized second derivative.&#13;The closer to 0, the more discarded tokens. Set to 1.0 to disable."></div>
                                         </small>
                                         <input class="neo-range-slider" type="range" id="tfs" name="volume" min="0" max="1" step="0.001">
                                         <input class="neo-range-input" type="number" min="0" max="1" step="0.001" data-for="tfs" id="tfs_counter">
@@ -868,7 +868,7 @@
                                                 </small>
                                             </a>
                                         </h4>
-                                        <textarea id="grammar" rows="4" class="text_pole textarea_compact monospace" placeholder="Type in the desired custom grammar"></textarea>
+                                        <textarea id="grammar" rows="4" class="text_pole textarea_compact monospace" data-i18n="[placeholder]Type in the desired custom grammar" placeholder="Type in the desired custom grammar"></textarea>
                                     </div>
                                     <div data-newbie-hidden name="KoboldSamplerOrderBlock" class="range-block flexFlowColumn">
                                         <hr class="wide100p">
@@ -1684,9 +1684,9 @@
                                             <input id="openai_image_inlining" type="checkbox" />
                                             <span data-i18n="Send inline images">Send inline images</span>
                                             <div id="image_inlining_hint" class="flexBasis100p toggle-description justifyLeft">
-                                                Sends images in prompts if the model supports it (e.g. GPT-4V, Claude 3 or Llava 13B).
-                                                Use the <code><i class="fa-solid fa-paperclip"></i></code> action on any message or the
-                                                <code><i class="fa-solid fa-wand-magic-sparkles"></i></code> menu to attach an image file to the chat.
+                                                <span data-i18n="image_inlining_hint_1">Sends images in prompts if the model supports it (e.g. GPT-4V, Claude 3 or Llava 13B).
+                                                Use the</span> <code><i class="fa-solid fa-paperclip"></i></code> <span data-i18n="image_inlining_hint_2">action on any message or the</span>
+                                                <code><i class="fa-solid fa-wand-magic-sparkles"></i></code> <span data-i18n="image_inlining_hint_3">menu to attach an image file to the chat.</span>
                                             </div>
                                         </label>
                                     </div>
@@ -3850,7 +3850,7 @@
                                 Character Handling
                             </h4>
                             <div title="If set in the advanced character definitions, this field will be displayed in the characters list." data-i18n="[title]If set in the advanced character definitions, this field will be displayed in the characters list.">
-                                <label for="aux_field" data-i18n="Char List Subheader"><small>Char List Subheader</small></label>
+                                <label for="aux_field"><small data-i18n="Char List Subheader">Char List Subheader</small></label>
                                 <select id="aux_field">
                                     <option data-i18n="Character Version" value="character_version">Character Version</option>
                                     <option data-i18n="Created by" value="creator">Created by</option>
@@ -4744,7 +4744,7 @@
         </div>
     </div>
     <!-- various fullscreen popups -->
-    <template id="shadow_popup_template">
+    <template id="shadow_popup_template" data-i18n="[popup_text_save]popup_text_save;[popup_text_yes]popup_text_yes;[popup_text_no]popup_text_no;[popup_text_cancel]popup_text_cancel;[popup_text_import]popup_text_import" popup_text_save="Save" popup_text_yes="Yes" popup_text_no="No" popup_text_cancel="Cancel" popup_text_import="Import"> <!-- localization data holder for popups -->
         <div class="shadow_popup">
             <div class="dialogue_popup">
                 <div class="dialogue_popup_holder">
@@ -4983,11 +4983,11 @@
     </div>
     <div id="background_template" class="template_element">
         <div class="bg_example flex-container" bgfile="" class="bg_example_img" title="">
-            <div title="Copy to system backgrounds" class="bg_button bg_example_copy fa-solid fa-file-arrow-up"></div>
-            <div title="Rename background" class="bg_button bg_example_edit fa-solid fa-pencil"></div>
-            <div title="Lock" class="bg_button bg_example_lock fa-solid fa-lock"></div>
-            <div title="Unlock" class="bg_button bg_example_unlock fa-solid fa-lock-open"></div>
-            <div title="Delete background" class="bg_button bg_example_cross fa-solid fa-circle-xmark"></div>
+            <div title="Copy to system backgrounds" data-i18n="[title]Copy to system backgrounds" class="bg_button bg_example_copy fa-solid fa-file-arrow-up"></div>
+            <div title="Rename background" data-i18n="[title]Rename background" class="bg_button bg_example_edit fa-solid fa-pencil"></div>
+            <div title="Lock" data-i18n="[title]Lock" class="bg_button bg_example_lock fa-solid fa-lock"></div>
+            <div title="Unlock" data-i18n="[title]Unlock" class="bg_button bg_example_unlock fa-solid fa-lock-open"></div>
+            <div title="Delete background" data-i18n="[title]Delete background" class="bg_button bg_example_cross fa-solid fa-circle-xmark"></div>
             <div class="BGSampleTitle">
             </div>
         </div>
@@ -5416,45 +5416,45 @@
             </div>
         </div>
         <div id="completion_prompt_manager_popup_edit">
-            <h3>Edit</h3>
+            <h3 data-i18n="prompt_manager_edit">Edit</h3>
             <div class="completion_prompt_manager_popup_entry">
                 <form class="completion_prompt_manager_popup_entry_form">
                     <div class="flex-container gap10px">
                         <div class="completion_prompt_manager_popup_entry_form_control flex1">
                             <label for="completion_prompt_manager_popup_entry_form_name">
-                                <span>Name</span>
+                                <span data-i18n="prompt_manager_name">Name</span>
                             </label>
-                            <div class="text_muted">A name for this prompt.</div>
+                            <div class="text_muted" data-i18n="A name for this prompt.">A name for this prompt.</div>
                             <input id="completion_prompt_manager_popup_entry_form_name" class="text_pole" type="text" name="name" />
                         </div>
                         <div class="completion_prompt_manager_popup_entry_form_control flex1">
                             <label for="completion_prompt_manager_popup_entry_form_role">
-                                <span>Role</span>
+                                <span data-i18n="Role">Role</span>
                             </label>
-                            <div class="text_muted">To whom this message will be attributed.</div>
+                            <div class="text_muted" data-i18n="To whom this message will be attributed.">To whom this message will be attributed.</div>
                             <select id="completion_prompt_manager_popup_entry_form_role" class="text_pole" name="role">
-                                <option value="system">System</option>
-                                <option value="user">User</option>
-                                <option value="assistant">AI Assistant</option>
+                                <option data-i18n="System" value="system">System</option>
+                                <option data-i18n="User" value="user">User</option>
+                                <option data-i18n="AI Assistant" value="assistant">AI Assistant</option>
                             </select>
                         </div>
                     </div>
                     <div class="flex-container gap10px">
                         <div class="completion_prompt_manager_popup_entry_form_control flex1">
                             <label for="completion_prompt_manager_popup_entry_form_injection_position">
-                                <span>Position</span>
+                                <span data-i18n="prompt_manager_position">Position</span>
                             </label>
-                            <div class="text_muted">Injection position. Next to other prompts (relative) or in-chat (absolute).</div>
+                            <div class="text_muted" data-i18n="Injection position. Next to other prompts (relative) or in-chat (absolute).">Injection position. Next to other prompts (relative) or in-chat (absolute).</div>
                             <select id="completion_prompt_manager_popup_entry_form_injection_position" class="text_pole" name="injection_position">
-                                <option value="0">Relative</option>
-                                <option value="1">Absolute</option>
+                                <option data-i18n="prompt_manager_relative" value="0">Relative</option>
+                                <option data-i18n="prompt_manager_absolute" value="1">Absolute</option>
                             </select>
                         </div>
                         <div id="completion_prompt_manager_depth_block" class="completion_prompt_manager_popup_entry_form_control flex1">
                             <label for="completion_prompt_manager_popup_entry_form_injection_depth">
-                                <span>Depth</span>
+                                <span data-i18n="prompt_manager_depth">Depth</span>
                             </label>
-                            <div class="text_muted">Injection depth. 0 = after the last message, 1 = before the last message, etc.</div>
+                            <div class="text_muted" data-i18n="Injection depth. 0 = after the last message, 1 = before the last message, etc.">Injection depth. 0 = after the last message, 1 = before the last message, etc.</div>
                             <input id="completion_prompt_manager_popup_entry_form_injection_depth" class="text_pole" type="number" name="injection_depth" min="0" max="999" value="4" />
                         </div>
                     </div>
@@ -5462,14 +5462,14 @@
                         <div class="flex-container alignItemsCenter">
                             <div class="flex1">
                                 <label for="completion_prompt_manager_popup_entry_form_prompt">
-                                    <span>Prompt</span>
+                                    <span data-i18n="Prompt">Prompt</span>
                                 </label>
-                                <div class="text_muted">The prompt to be sent.</div>
+                                <div class="text_muted" data-i18n="The prompt to be sent.">The prompt to be sent.</div>
                             </div>
                             <div id="completion_prompt_manager_forbid_overrides_block">
-                                <label class="checkbox_label" for="completion_prompt_manager_popup_entry_form_forbid_overrides" title="This prompt cannot be overridden by character cards, even if overrides are preferred.">
+                                <label class="checkbox_label" for="completion_prompt_manager_popup_entry_form_forbid_overrides" data-i18n="[title]This prompt cannot be overridden by character cards, even if overrides are preferred." title="This prompt cannot be overridden by character cards, even if overrides are preferred.">
                                     <input type="checkbox" id="completion_prompt_manager_popup_entry_form_forbid_overrides" name="forbid_overrides" />
-                                    <span>Forbid Overrides</span>
+                                    <span data-i18n="prompt_manager_forbid_overrides">Forbid Overrides</span>
                                 </label>
                             </div>
                         </div>
@@ -5578,6 +5578,10 @@
                 <li><span data-i18n="welcome_message_part_4">Type</span> <code>/help</code> <span data-i18n="welcome_message_part_5">in chat for commands and macros.</span></li>
                 <li><span data-i18n="welcome_message_part_6">Join the</span> <a href="https://discord.gg/sillytavern" data-i18n="Discord server" target="_blank">Discord server</a> <span data-i18n="welcome_message_part_7">for info and announcements.</span></li>
             </ul>
+            <div id="onboarding-UI-language-block" class="flex-container alignItemsBaseline">
+                <span data-i18n="UI Language">Language:</span>
+                <select id="onboarding_ui_language_select" class="flex1 margin0">
+                    <option value="en">English</option></select></div>
             <b data-i18n="SillyTavern is aimed at advanced users.">
                 SillyTavern is aimed at advanced users.
             </b>
@@ -5603,7 +5607,7 @@
                 <span>
                     <span class="menu_button menu_button_icon external_import_button">
                         <i class="fa-solid fa-cloud-arrow-down"></i>
-                        <span>Import</span>
+                        <span data-i18n="onboarding_import">Import</span>
                     </span>
                     <span data-i18n="from supported sources or view">
                         from supported sources or view
diff --git a/public/locales/ru-ru.json b/public/locales/ru-ru.json
index 6c730a669..9e0953316 100644
--- a/public/locales/ru-ru.json
+++ b/public/locales/ru-ru.json
@@ -33,7 +33,7 @@
     "Variability parameter for Mirostat outputs": "Параметр изменчивости для выходных данных Mirostat.",
     "Learning rate of Mirostat": "Скорость обучения Mirostat.",
     "Strength of the Contrastive Search regularization term. Set to 0 to disable CS": "Сила условия регуляризации контрастивного поиска. Установите значение 0, чтобы отключить CS.",
-    "Temperature Last": "Temperature Last",
+    "Temperature Last": "Температура последней",
     "Use the temperature sampler last": "Использовать Temperature сэмплер в последнюю очередь. Это почти всегда разумно.\nПри включении: сначала выборка набора правдоподобных токенов, затем применение Temperature для корректировки их относительных вероятностей (технически, логитов).\nПри отключении: сначала применение Temperature для корректировки относительных вероятностей ВСЕХ токенов, затем выборка правдоподобных токенов из этого.\nОтключение Temperature Last увеличивает вероятности в хвосте распределения, что увеличивает шансы получить несогласованный ответ.",
     "LLaMA / Mistral / Yi models only": "Только для моделей LLaMA / Mistral / Yi. Перед этим обязательно выберите подходящий токенизатор.\nПоследовательности, которых не должно быть на выходе.\nОдна на строку. Текст или [идентификаторы токенов].\nМногие токены имеют пробел впереди. Используйте счетчик токенов, если не уверены.",
     "Example: some text [42, 69, 1337]": "Пример:\nкакой-то текст\n[42, 69, 1337]",
@@ -128,7 +128,7 @@
     "Jailbreak prompt": "Джейлбрейк-промпт",
     "Prompt that is used when the Jailbreak toggle is on": "Промпт, применяемый при включенном джейлбрейке.",
     "Impersonation prompt": "Промпт для перевоплощения",
-    "Prompt that is used for Impersonation function": "Промпт, применяемый при генерации действий за пользователя",
+    "Prompt that is used for Impersonation function": "Промпт, применяемый при генерации действий от лица пользователя",
     "Logit Bias": "Смещение логитов",
     "Helps to ban or reenforce the usage of certain words": "Запрещает или поощряет использование определенных слов",
     "View / Edit bias preset": "Просмотр / Редактирование пресета смещения",
@@ -179,8 +179,8 @@
     "Novel AI Model": "Модель NovelAI",
     "If you are using:": "Если вы используете:",
     "oobabooga/text-generation-webui": "",
-    "Make sure you run it with": "Убедитесь, что вы запустили его с",
-    "flag": "флажком",
+    "Make sure you run it with": "Обязательно запускайте его с флагом",
+    "flag": "",
     "API key (optional)": "Ключ API (опционально)",
     "Server url": "URL-адрес сервера",
     "Custom model (optional)": "Пользовательская модель (опционально)",
@@ -195,13 +195,13 @@
     "Example: ws://127.0.0.1:5005/api/v1/stream": "Пример:  ws://127.0.0.1:5005/api/v1/stream",
     "Mancer API key": "Ключ от Mancer API",
     "Example: https://neuro.mancer.tech/webui/MODEL/api": "Пример: https://neuro.mancer.tech/webui/MODEL/api",
-    "to get your OpenAI API key.": "для получения ключа от OpenAI API",
+    "to get your OpenAI API key.": "для получения ключа от API OpenAI",
     "Window AI Model": "Модель Window AI",
     "OpenAI Model": "Модель OpenAI",
     "Claude API Key": "Ключ от Claude API",
     "Get your key from": "Получите ключ в",
     "Anthropic's developer console": "консоли разработчика Anthropic",
-    "Slack and Poe cookies will not work here, do not bother trying.": "Файлы cookie Slack и Poe здесь не подойдут, можете их не пробовать.",
+    "Slack and Poe cookies will not work here, do not bother trying.": "Cookie от Slack и Poe здесь не подойдут, можете их не пробовать.",
     "Claude Model": "Модель Claude",
     "Scale API Key": "Ключ от Scale API",
     "Alt Method": "Альтернативный метод",
@@ -228,7 +228,7 @@
     "Disable example chats formatting": "Отключить форматирование примеров чата",
     "Disable chat start formatting": "Отключить форматирование начала чата",
     "Custom Chat Separator": "Кастомный разделитель для чата",
-    "Replace Macro in Custom Stopping Strings": "Заменить макрос в пользовательских стоп-строках",
+    "Replace Macro in Custom Stopping Strings": "Заменить макросы в пользовательских стоп-строках",
     "Strip Example Messages from Prompt": "Удалить примеры сообщений из подсказки",
     "Story String": "Строка истории",
     "Example Separator": "Пример разделителя",
@@ -535,13 +535,13 @@
     "Streaming FPS": "FPS для стриминга",
     "Gestures": "Жесты",
     "Message IDs": "ID сообщений",
-    "Prefer Character Card Prompt": "Предпочитать промпт из карточки персонажа",
-    "Prefer Character Card Jailbreak": "Предпочитать джейлбрейк из карточки керсонажа",
+    "Prefer Character Card Prompt": "Приоритет промпту из карточки персонажа",
+    "Prefer Character Card Jailbreak": "Приоритет джейлбрейку из карточки персонажа",
     "Press Send to continue": "Кнопка отправки продолжает сообщение",
     "Quick 'Continue' button": "Кнопка быстрого продолжения",
     "Log prompts to console": "Выводить промпты в консоль",
-    "Never resize avatars": "Никогда не менять размер аватаров",
-    "Show avatar filenames": "Показывать названия файлов аватаров",
+    "Never resize avatars": "Не менять размер аватарок",
+    "Show avatar filenames": "Показывать названия файлов аватарок",
     "Import Card Tags": "Импорт тегов карточки",
     "Confirm message deletion": "Подтверждение удаления сообщений",
     "Spoiler Free Mode": "Режим без спойлеров",
@@ -562,7 +562,7 @@
     "Reduce chat height, and put a static sprite behind the chat window": "Уменьшить высоту чата и поместить статичный спрайт за окном чата.",
     "Always show the full list of the Message Actions context items for chat messages, instead of hiding them behind '...'": "Всегда показывать полный список действий с сообщением, а не прятать их за '...'.",
     "Alternative UI for numeric sampling parameters with fewer steps": "Альтернативный пользовательский интерфейс для числовых параметров выборки с меньшим количеством шагов.",
-    "Entirely unrestrict all numeric sampling parameters": "Полностью разграничить все числовые параметры выборки.",
+    "Entirely unrestrict all numeric sampling parameters": "Снять ограничения со всех числовых сэмплеров.",
     "Time the AI's message generation, and show the duration in the chat log": "Время генерации сообщений ИИ и его показ в журнале чата.",
     "Show a timestamp for each message in the chat log": "Показывать временную метку для каждого сообщения в журнале чата.",
     "Show an icon for the API that generated the message": "Показать значок API, сгенерировавшего сообщение.",
@@ -834,7 +834,7 @@
     "Sampler Priority": "Приоритет сэмплеров",
     "Ooba only. Determines the order of samplers.": "Только Ooba. Определяет порядок сэмплеров.",
     "Load default order": "Загрузить стандартный порядок",
-    "Max Tokens Second": "Максимальное количество токенов в секунду",
+    "Max Tokens Second": "Макс. кол-во токенов в секунду",
     "CFG": "CFG",
     "No items": "Нет элементов",
     "Extras API key (optional)": "Ключ от Extras API (необязательно)",
@@ -868,10 +868,10 @@
     "Send names in the message objects. Helps the model to associate messages with characters.": "Отправить имена в объектах сообщений. Помогает модели ассоциировать сообщения с персонажами.",
     "Continue prefill": "Префилл для продолжения",
     "Continue sends the last message as assistant role instead of system message with instruction.": "Продолжение отправляет последнее сообщение в роли ассистента, вместо системного сообщения с инструкцией.",
-    "Squash system messages": "Склеивать сообщения системыы",
-    "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Объединяет последовательные системные сообщения в одно (за исключением примеров диалогов). Может улучшить согласованность для некоторых моделей.",
-    "Send inline images": "Отправлять встроенные изображения",
-    "Assistant Prefill": "Префилл от ассистента",
+    "Squash system messages": "Склеивать сообщения системы",
+    "Combines consecutive system messages into one (excluding example dialogues). May improve coherence for some models.": "Объединяет последовательные системные сообщения в одно (за исключением примеров диалогов). У некоторых моделей может улучшить логичность ответов.",
+    "Send inline images": "Отправлять inline-картинки",
+    "Assistant Prefill": "Префилл для ассистента",
     "Start Claude's answer with...": "Начать ответ Клода с...",
     "Use system prompt (Claude 2.1+ only)": "Использовать системный промпт (только Claude 2.1+)",
     "Send the system prompt for supported models. If disabled, the user message is added to the beginning of the prompt.": "Отправлять системный промпт для поддерживаемых моделей. Если отключено, сообщение пользователя добавляется в начало промпта.",
@@ -880,7 +880,7 @@
     "Insert prompt": "Вставить промпт",
     "Delete prompt": "Удалить промпт",
     "Import a prompt list": "Импортировать список промптов",
-    "Export this prompt list": "Экспортировать этот список промпт",
+    "Export this prompt list": "Экспортировать этот список промптов",
     "Reset current character": "Сбросить текущего персонажа",
     "New prompt": "Новый промпт",
     "Tokens": "токенов",
@@ -1176,5 +1176,89 @@
     "ext_sum_injection_template": "Шаблон для инжекта",
     "ext_sum_memory_template_placeholder": "Макрос {{summary}} будет заменён на содержимое пересказа",
     "ext_sum_injection_position": "Куда инжектить",
-    "How many messages before the current end of the chat.": "Сколько сообщений от конца чата."
+    "How many messages before the current end of the chat.": "Сколько сообщений от конца чата.",
+    "Official Documentation": "официальной документацией",
+    "Change it later in the 'User Settings' panel.": "Его можно будет выключить в меню \"Настройки пользователя\"",
+    "Looking for AI characters?": "Ищете ИИ-персонажей?",
+    "onboarding_import": "Импортируйте",
+    "from supported sources or view": "из источника или посмотрите",
+    "Sample characters": "Стандартных персонажей",
+    "popup_text_save": "Сохранить",
+    "popup_text_yes": "Да",
+    "popup_text_no": "Нет",
+    "popup_text_cancel": "Отмена",
+    "Enter the URL of the content to import": "Введите URL-адрес импортируемого контента",
+    "Supported sources:": "Поддерживаются следующие источники:",
+    "char_import_example": "Пример:",
+    "char_import_1": "Персонаж с Chub (прямая ссылка или ID)",
+    "char_import_2": "Лорбук с Chub (прямая ссылка или ID)",
+    "char_import_3": "Персонаж с JanitorAI (прямая ссылка или UUID)",
+    "char_import_4": "Персонаж с Pygmalion.chat (прямая ссылка или UUID)",
+    "char_import_5": "Персонаж с AICharacterCard.com (прямая ссылка или ID)",
+    "char_import_6": "Прямая ссылка на PNG-файл (чтобы узнать список разрешённых хостов, загляните в",
+    "char_import_7": ")",
+    "popup_text_import": "Импортировать",
+    "Grammar String": "Грамматика",
+    "GNBF or ENBF, depends on the backend in use. If you're using this you should know which.": "GNBF или ENBF, зависит от бэкенда. Если вы это используете, то, скорее всего, сами знаете, какой именно.",
+    "Account": "Аккаунт",
+    "Hi,": "Привет,",
+    "To enable multi-account features, restart the SillyTavern server with": "Чтобы активировать систему аккаунтов, перезапустите SillyTavern, выставив",
+    "set to true in the config.yaml file.": "в файле config.yaml в положение true.",
+    "Account Info": "Об аккаунте",
+    "Handle:": "Хэндл:",
+    "Role:": "Роль:",
+    "Created:": "Создан:",
+    "Password:": "Пароль:",
+    "This account is password protected.": "Аккаунт защищён паролем.",
+    "This account is not password protected.": "Аккаунт не защищён паролем.",
+    "Account Actions": "Действия",
+    "Settings Snapshots": "Снимки настроек",
+    "Manage your settings snapshots.": "Управление снимками настроек.",
+    "Download Backup": "Скачать бэкап",
+    "Download a complete backup of your user data.": "Скачать полный бэкап данных пользователя.",
+    "Danger Zone": "Опасно",
+    "Reset Settings": "Сбросить настройки",
+    "Reset your settings to factory defaults.": "Сбросить настройки до заводских.",
+    "Reset Everything": "Сбросить всё",
+    "Wipe all user data and reset your account to factory settings.": "Стереть все данные пользователя и сбросить аккаунт до заводских настроек.",
+    "Set your custom avatar.": "Установить аватарку",
+    "Remove your custom avatar.": "Сбросить аватарку",
+    "Make a Snapshot": "Сделать снимок",
+    "Avoid cropping and resizing imported character images. When off, crop/resize to 512x768": "Не менять размер картинок у импортируемых персонажей. При отключении все картинки будут приводиться к размеру 512х768",
+    "Char List Subheader": "Доп. заголовок в списке персонажей",
+    "# Messages to Load": "Сколько сообщений загружать",
+    "(0 = All)": "(0 = все)",
+    "Theme Colors": "Цвета темы",
+    "Specify colors for your theme.": "Настройте собственные цвета для вашей темы.",
+    "Update speed of streamed text.": "Скорость обновления текста при стриминге.",
+    "The number of chat history messages to load before pagination.": "Кол-во сообщений чата, загружаемых перед пагинацией.",
+    "Chat Width": "Ширина чата",
+    "Width of the main chat window in % of screen width": "Ширина окна с чатом, в % от ширины экрана",
+    "Blur strength on UI panels.": "Сила размытия на панелях UI.",
+    "Font size": "Размер шрифта",
+    "Strength of the text shadows": "Размер теней, отбрасываемых текстом",
+    "Total Tokens:": "Всего токенов:",
+    "prompt_manager_edit": "Редактирование",
+    "prompt_manager_tokens": "Токенов",
+    "prompt_manager_name": "Имя",
+    "A name for this prompt.": "Имя данного промпта.",
+    "To whom this message will be attributed.": "От чьего лица будет отправляться сообщение.",
+    "AI Assistant": "ИИ-ассистент",
+    "prompt_manager_position": "Точка инжекта",
+    "Injection position. Next to other prompts (relative) or in-chat (absolute).": "Как рассчитывать позицию для инжекта. Она может располагаться по отношению к другим промптам (относительная) либо по отношению к чату (абсолютная).",
+    "prompt_manager_relative": "Относительная",
+    "prompt_manager_absolute": "Абсолютная",
+    "prompt_manager_depth": "Глубина",
+    "Injection depth. 0 = after the last message, 1 = before the last message, etc.": "Глубина вставки. 0 = после последнего сообщения, 1 = перед последним сообщением, и т.д.",
+    "The prompt to be sent.": "Отправляемый ИИ промпт.",
+    "prompt_manager_forbid_overrides": "Запретить перезапись",
+    "This prompt cannot be overridden by character cards, even if overrides are preferred.": "Карточка персонажа не сможет перезаписать этот промпт, даже если настройки отдают приоритет именно ей.",
+    "image_inlining_hint_1": "Отправлять картинки как часть промпта, если позволяет модель (такой функционал поддерживают GPT-4V, Claude 3 или Llava 13B). Чтобы добавить в чат изображение, используйте на нужном сообщении действие",
+    "image_inlining_hint_2": ". Также это можно сделать через меню",
+    "image_inlining_hint_3": ".",
+    "Contest Winners": "Победители конкурса",
+    "Rename background": "Переименовать фон",
+    "Lock": "Закрепить",
+    "Unlock": "Открепить",
+    "Delete background": "Удалить фон"
 }
diff --git a/public/script.js b/public/script.js
index f9e781b85..5b92efc60 100644
--- a/public/script.js
+++ b/public/script.js
@@ -205,7 +205,7 @@ import {
     instruct_presets,
     selectContextPreset,
 } from './scripts/instruct-mode.js';
-import { initLocales } from './scripts/i18n.js';
+import { initLocales, applyLocale } from './scripts/i18n.js';
 import { getFriendlyTokenizerName, getTokenCount, getTokenCountAsync, getTokenizerModel, initTokenizers, saveTokenCache } from './scripts/tokenizers.js';
 import {
     user_avatar,
@@ -854,12 +854,12 @@ async function firstLoadInit() {
         throw new Error('Initialization failed');
     }
 
-    await getSystemMessages();
-    sendSystemMessage(system_message_types.WELCOME);
     await getClientVersion();
     await readSecretState();
+    initLocales(); // this function needs to be executed this late because otherwise, locale file fails to load on time sometimes
+    await getSystemMessages();
+    sendSystemMessage(system_message_types.WELCOME);
     await getSettings();
-    initLocales();
     initTags();
     await getUserAvatars(true, user_avatar);
     await getCharacters();
@@ -10370,17 +10370,17 @@ jQuery(async function () {
     });
 
     $(document).on('click', '.external_import_button, #external_import_button', async () => {
-        const html = `<h3>Enter the URL of the content to import</h3>
-        Supported sources:<br>
+        const html = applyLocale(`<h3 data-i18n="Enter the URL of the content to import">Enter the URL of the content to import</h3>
+        <span data-i18n="Supported sources:">Supported sources:</span><br>
         <ul class="justifyLeft">
-            <li>Chub Character (Direct Link or ID)<br>Example: <tt>Anonymous/example-character</tt></li>
-            <li>Chub Lorebook (Direct Link or ID)<br>Example: <tt>lorebooks/bartleby/example-lorebook</tt></li>
-            <li>JanitorAI Character (Direct Link or UUID)<br>Example: <tt>ddd1498a-a370-4136-b138-a8cd9461fdfe_character-aqua-the-useless-goddess</tt></li>
-            <li>Pygmalion.chat Character (Direct Link or UUID)<br>Example: <tt>a7ca95a1-0c88-4e23-91b3-149db1e78ab9</tt></li>
-            <li>AICharacterCard.com Character (Direct Link or ID)<br>Example: <tt>AICC/aicharcards/the-game-master</tt></li>
-            <li>Direct PNG Link (refer to <code>config.yaml</code> for allowed hosts)<br>Example: <tt>https://files.catbox.moe/notarealfile.png</tt></li>
-        <ul>`;
-        const input = await callGenericPopup(html, POPUP_TYPE.INPUT, '', { okButton: 'Import', rows: 4 });
+            <li><span data-i18n="char_import_1">Chub Character (Direct Link or ID)</span><br><span data-i18n="char_import_example">Example:</span> <tt>Anonymous/example-character</tt></li>
+            <li><span data-i18n="char_import_2">Chub Lorebook (Direct Link or ID)</span><br><span data-i18n="char_import_example">Example:</span> <tt>lorebooks/bartleby/example-lorebook</tt></li>
+            <li><span data-i18n="char_import_3">JanitorAI Character (Direct Link or UUID)</span><br><span data-i18n="char_import_example">Example:</span> <tt>ddd1498a-a370-4136-b138-a8cd9461fdfe_character-aqua-the-useless-goddess</tt></li>
+            <li><span data-i18n="char_import_4">Pygmalion.chat Character (Direct Link or UUID)</span><br><span data-i18n="char_import_example">Example:</span> <tt>a7ca95a1-0c88-4e23-91b3-149db1e78ab9</tt></li>
+            <li><span data-i18n="char_import_5">AICharacterCard.com Character (Direct Link or ID)</span><br><span data-i18n="char_import_example">Example:</span> <tt>AICC/aicharcards/the-game-master</tt></li>
+            <li><span data-i18n="char_import_6">Direct PNG Link (refer to</span> <code>config.yaml</code><span data-i18n="char_import_7"> for allowed hosts)</span><br><span data-i18n="char_import_example">Example:</span> <tt>https://files.catbox.moe/notarealfile.png</tt></li>
+        <ul>`);
+        const input = await callGenericPopup(html, POPUP_TYPE.INPUT, '', { okButton: $('#shadow_popup_template').attr('popup_text_import'), rows: 4 });
 
         if (!input) {
             console.debug('Custom content import cancelled');
diff --git a/public/scripts/PromptManager.js b/public/scripts/PromptManager.js
index d45da25bf..97d44164c 100644
--- a/public/scripts/PromptManager.js
+++ b/public/scripts/PromptManager.js
@@ -6,6 +6,7 @@ import { Message, TokenHandler } from './openai.js';
 import { power_user } from './power-user.js';
 import { debounce, waitUntilCondition, escapeHtml } from './utils.js';
 import { debounce_timeout } from './constants.js';
+import { applyLocale } from './i18n.js'
 
 function debouncePromise(func, delay) {
     let timeoutId;
@@ -1097,12 +1098,12 @@ class PromptManager {
     createQuickEdit(identifier, title) {
         const prompt = this.getPromptById(identifier);
         const textareaIdentifier = `${identifier}_prompt_quick_edit_textarea`;
-        const html = `<div class="range-block m-t-1">
+        const html = applyLocale(`<div class="range-block m-t-1">
                         <div class="justifyLeft" data-i18n="${title}">${title}</div>
                         <div class="wide100p">
                             <textarea id="${textareaIdentifier}" class="text_pole textarea_compact" rows="6" placeholder="">${prompt.content}</textarea>
                         </div>
-                    </div>`;
+                    </div>`);
 
         const quickEditContainer = document.getElementById('quick-edit-container');
         quickEditContainer.insertAdjacentHTML('afterbegin', html);
@@ -1355,18 +1356,18 @@ class PromptManager {
 
         const totalActiveTokens = this.tokenUsage;
 
-        promptManagerDiv.insertAdjacentHTML('beforeend', `
+        promptManagerDiv.insertAdjacentHTML('beforeend', applyLocale(`
             <div class="range-block">
                 ${this.error ? errorDiv : ''}
                 <div class="${this.configuration.prefix}prompt_manager_header">
                     <div class="${this.configuration.prefix}prompt_manager_header_advanced">
                         <span data-i18n="Prompts">Prompts</span>
                     </div>
-                    <div>Total Tokens: ${totalActiveTokens} </div>
+                    <div><span data-i18n="Total Tokens:">Total Tokens:</span> ${totalActiveTokens} </div>
                 </div>
                 <ul id="${this.configuration.prefix}prompt_manager_list" class="text_pole"></ul>
             </div>
-        `);
+        `));
 
         this.listElement = promptManagerDiv.querySelector(`#${this.configuration.prefix}prompt_manager_list`);
 
@@ -1384,7 +1385,7 @@ class PromptManager {
                 selectedPromptIndex = 0;
             }
 
-            const footerHtml = `
+            const footerHtml = applyLocale(`
                 <div class="${this.configuration.prefix}prompt_manager_footer">
                     <select id="${this.configuration.prefix}prompt_manager_footer_append_prompt" class="text_pole" name="append-prompt">
                         ${promptsHtml}
@@ -1396,7 +1397,7 @@ class PromptManager {
                     <a class="menu_button fa-undo fa-solid" id="prompt-manager-reset-character" title="Reset current character" data-i18n="[title]Reset current character"></a>
                     <a class="menu_button fa-plus-square fa-solid" title="New prompt" data-i18n="[title]New prompt"></a>
                 </div>
-            `;
+            `);
 
             const rangeBlockDiv = promptManagerDiv.querySelector('.range-block');
             const headerDiv = promptManagerDiv.querySelector('.completion_prompt_manager_header');
@@ -1410,12 +1411,12 @@ class PromptManager {
             footerDiv.querySelector('select').selectedIndex = selectedPromptIndex;
 
             // Add prompt export dialogue and options
-            const exportForCharacter = `
+            const exportForCharacter = applyLocale(`
             <div class="row">
                 <a class="export-promptmanager-prompts-character list-group-item" data-i18n="Export for character">Export for character</a>
                 <span class="tooltip fa-solid fa-info-circle" title="Export prompts for this character, including their order."></span>
-            </div>`;
-            const exportPopup = `
+            </div>`);
+            const exportPopup = applyLocale(`
                     <div id="prompt-manager-export-format-popup" class="list-group">
                         <div class="prompt-manager-export-format-popup-flex">
                             <div class="row">
@@ -1425,7 +1426,7 @@ class PromptManager {
                             ${'global' === this.configuration.promptOrder.strategy ? '' : exportForCharacter}
                         </div>
                 </div>
-                `;
+                `);
 
             rangeBlockDiv.insertAdjacentHTML('beforeend', exportPopup);
 
@@ -1468,16 +1469,16 @@ class PromptManager {
 
         const { prefix } = this.configuration;
 
-        let listItemHtml = `
+        let listItemHtml = applyLocale(`
             <li class="${prefix}prompt_manager_list_head">
                 <span data-i18n="Name">Name</span>
                 <span></span>
-                <span class="prompt_manager_prompt_tokens" data-i18n="Tokens">Tokens</span>
+                <span class="prompt_manager_prompt_tokens" data-i18n="Tokens;prompt_manager_tokens">Tokens</span>
             </li>
             <li class="${prefix}prompt_manager_list_separator">
                 <hr>
             </li>
-        `;
+        `);
 
         this.getPromptsForCharacter(this.activeCharacter).forEach(prompt => {
             if (!prompt) return;
diff --git a/public/scripts/i18n.js b/public/scripts/i18n.js
index c4e837939..5f2d05bca 100644
--- a/public/scripts/i18n.js
+++ b/public/scripts/i18n.js
@@ -126,16 +126,17 @@ export function applyLocale(root = document) {
 
 
 function addLanguagesToDropdown() {
+    const uiLanguageSelects = $('#ui_language_select, #onboarding_ui_language_select');
     for (const langObj of langs) { // Set the value to the language code
         const option = document.createElement('option');
         option.value = langObj['lang']; // Set the value to the language code
         option.innerText = langObj['display']; // Set the display text to the language name
-        $('#ui_language_select').append(option);
+        uiLanguageSelects.append(option);
     }
 
     const selectedLanguage = localStorage.getItem(storageKey);
     if (selectedLanguage) {
-        $('#ui_language_select').val(selectedLanguage);
+        uiLanguageSelects.val(selectedLanguage);
     }
 }
 
@@ -144,7 +145,7 @@ export function initLocales() {
     addLanguagesToDropdown();
     updateSecretDisplay();
 
-    $('#ui_language_select').on('change', async function () {
+    $('#ui_language_select, #onboarding_ui_language_select').on('change', async function () {
         const language = String($(this).val());
 
         if (language) {
diff --git a/public/scripts/popup.js b/public/scripts/popup.js
index c69aa6e60..f7dfe9f81 100644
--- a/public/scripts/popup.js
+++ b/public/scripts/popup.js
@@ -68,9 +68,10 @@ export class Popup {
         if (allowHorizontalScrolling) dlg.classList.add('horizontal_scrolling_dialogue_popup');
         if (allowVerticalScrolling) dlg.classList.add('vertical_scrolling_dialogue_popup');
 
+        const localeDataHolder = $('#shadow_popup_template');
         this.ok.textContent = okButton ?? 'OK';
-        this.cancel.textContent = cancelButton ?? 'Cancel';
-
+        this.cancel.textContent = cancelButton ?? localeDataHolder.attr('popup_text_cancel');
+        
         switch (type) {
             case POPUP_TYPE.TEXT: {
                 this.input.style.display = 'none';
@@ -79,13 +80,13 @@ export class Popup {
             }
             case POPUP_TYPE.CONFIRM: {
                 this.input.style.display = 'none';
-                this.ok.textContent = okButton ?? 'Yes';
-                this.cancel.textContent = cancelButton ?? 'No';
+                this.ok.textContent = okButton ?? localeDataHolder.attr('popup_text_yes');
+                this.cancel.textContent = cancelButton ?? localeDataHolder.attr('popup_text_no');
                 break;
             }
             case POPUP_TYPE.INPUT: {
                 this.input.style.display = 'block';
-                this.ok.textContent = okButton ?? 'Save';
+                this.ok.textContent = okButton ?? localeDataHolder.attr('popup_text_save');
                 break;
             }
             default: {
diff --git a/public/scripts/templates/userProfile.html b/public/scripts/templates/userProfile.html
index cf17c9c85..e1eb34ecd 100644
--- a/public/scripts/templates/userProfile.html
+++ b/public/scripts/templates/userProfile.html
@@ -1,17 +1,17 @@
 <div class="flex-container flexFlowColumn justifyLeft flexGap10">
     <div>
         <h2 class="marginBot10 flex-container">
-            <span>Hi,</span><span class="userName margin0"></span>
+            <span data-i18n="Hi,">Hi,</span><span class="userName margin0"></span>
             <div data-require-accounts class="userChangeNameButton right_menu_button" title="Change display name.">
                 <i class="fa-fw fa-solid fa-pencil fa-xs"></i>
             </div>
         </h2>
         <div class="accountsDisabledHint" style="display: none;">
-            To enable multi-account features, restart the SillyTavern server with <code>enableUserAccounts</code> set to true in the config.yaml file.
+            <span data-i18n="To enable multi-account features, restart the SillyTavern server with">To enable multi-account features, restart the SillyTavern server with</span> <code>enableUserAccounts</code> <span data-i18n="set to true in the config.yaml file.">set to true in the config.yaml file.</span>
         </div>
     </div>
     <div>
-        <h3>
+        <h3 data-i18n="Account Info">
             Account Info
         </h3>
         <div class="flex-container flexGap10">
@@ -20,10 +20,10 @@
                     <img src="img/ai4.png" alt="avatar">
                 </div>
                 <div class="flex-container alignItemsCenter">
-                    <div class="userAvatarChange right_menu_button" title="Set your custom avatar.">
+                    <div class="userAvatarChange right_menu_button" data-i18n="[title]Set your custom avatar." title="Set your custom avatar.">
                         <i class="fa-fw fa-solid fa-image"></i>
                     </div>
-                    <div class="userAvatarRemove right_menu_button" title="Remove your custom avatar.">
+                    <div class="userAvatarRemove right_menu_button" data-i18n="[title]Remove your custom avatar." title="Remove your custom avatar.">
                         <i class="fa-fw fa-solid fa-trash"></i>
                     </div>
                 </div>
@@ -49,15 +49,15 @@
                     </div>
                     <div>
                         <span data-i18n="Password:">Password:</span>
-                        <i class="hasPassword fa-fw fa-solid fa-lock" title="This account is password protected."></i>
-                        <i class="noPassword fa-fw fa-solid fa-lock-open" title="This account is not password protected."></i>
+                        <i class="hasPassword fa-fw fa-solid fa-lock" data-i18n="[title]This account is password protected." title="This account is password protected."></i>
+                        <i class="noPassword fa-fw fa-solid fa-lock-open" data-i18n="[title]This account is not password protected." title="This account is not password protected."></i>
                     </div>
                 </div>
             </div>
         </div>
     </div>
     <div>
-        <h3>
+        <h3 data-i18n="Account Actions">
             Account Actions
         </h3>
         <div class="flex-container flexFlowColumn flexNoGap">
@@ -68,11 +68,11 @@
                 </div>
             </div>
             <div class="flex-container">
-                <div class="userSettingsSnapshotsButton menu_button menu_button_icon" title="Manage your settings snapshots.">
+                <div class="userSettingsSnapshotsButton menu_button menu_button_icon" data-i18n="[title]Manage your settings snapshots." title="Manage your settings snapshots.">
                     <i class="fa-fw fa-solid fa-camera"></i>
                     <span data-i18n="Settings Snapshots">Settings Snapshots</span>
                 </div>
-                <div class="userBackupButton menu_button menu_button_icon" title="Download a complete backup of your user data.">
+                <div class="userBackupButton menu_button menu_button_icon" data-i18n="[title]Download a complete backup of your user data." title="Download a complete backup of your user data.">
                     <i class="fa-fw fa-solid fa-download"></i>
                     <span data-i18n="Download Backup">Download Backup</span>
                 </div>
@@ -80,15 +80,15 @@
         </div>
     </div>
     <div>
-        <h3>
+        <h3 data-i18n="Danger Zone">
             Danger Zone
         </h3>
         <div class="flex-container">
-            <div class="userResetSettingsButton menu_button menu_button_icon" title="Reset your settings to factory defaults.">
+            <div class="userResetSettingsButton menu_button menu_button_icon" data-i18n="[title]Reset your settings to factory defaults." title="Reset your settings to factory defaults.">
                 <i class="fa-fw fa-solid fa-cog warning"></i>
                 <span data-i18n="Reset Settings">Reset Settings</span>
             </div>
-            <div class="userResetAllButton menu_button menu_button_icon" title="Wipe all user data and reset your account to factory settings.">
+            <div class="userResetAllButton menu_button menu_button_icon" data-i18n="[title]Wipe all user data and reset your account to factory settings." title="Wipe all user data and reset your account to factory settings.">
                 <i class="fa-fw fa-solid fa-skull warning"></i>
                 <span data-i18n="Reset Everything">Reset Everything</span>
             </div>