diff --git a/README.md b/README.md
index 51b38d3c..7cb6fcc9 100644
--- a/README.md
+++ b/README.md
@@ -17,10 +17,11 @@ cobalt doesn't remux any videos, so you get videos of max quality available (unl
 
 ## What still has to be done
 - [ ] Quality switching for bilibili and Twitter
-- [ ] Clean up the mess that localisation is right now
-    - [ ] Sort contents of .json files
-    - [ ] Rename each entry key to be less linked to specific service (entries like youtubeBroke are awful, I'm sorry)
-- [ ] Add support for more languages when localisation clean up is done
+- [ ] Language picker in settings
+- [x] Clean up the mess that localisation is right now
+    - [x] Sort contents of .json files
+    - [x] Rename each entry key to be less linked to specific service (entries like youtubeBroke are awful, I'm sorry)
+- [x] Add support for more languages when localisation clean up is done
 - [ ] Use esmbuild to minify frontend css and js
 - [ ] Make switch buttons in settings selectable with keyboard
 - [ ] Do something about changelog because the way it is right now is not really great
diff --git a/src/config.json b/src/config.json
index 91272789..528d3212 100644
--- a/src/config.json
+++ b/src/config.json
@@ -5,7 +5,7 @@
     "maxVideoDuration": 1920000,
     "genericUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
     "repo": "https://github.com/wukko/cobalt",
-    "supportedLanguages": ["en"],
+    "supportedLanguages": ["en", "ru"],
     "authorInfo": {
         "name": "wukko",
         "link": "https://wukko.me/",
diff --git a/src/i18n/en/apiError.json b/src/i18n/en/apiError.json
index 9a1969d7..99b0f7cf 100644
--- a/src/i18n/en/apiError.json
+++ b/src/i18n/en/apiError.json
@@ -1,21 +1,18 @@
 {
-    "generic": "something went wrong and i couldn't get the video. you can try again,",
+    "generic": "something went wrong and i couldn't get anything for you. you can try again, but if issue persists, please <a class=\"text-backdrop nowrap\" href=\"{repo}\">let me know</a>.",
     "notSupported": "it seems like this service is not supported yet or your link is invalid.",
-    "brokenLink": "{s} is supported, but something is wrong with your link.",
-    "noURL": "i can't guess what you want to download! please give me a link.",
-    "tryAgain": "\ncheck the link and try again.",
-    "letMeKnow": "but if issue persists, please <a class=\"text-backdrop nowrap\" href=\"{repo}\">let me know</a>.",
-    "fatal": "something went wrong and page couldn't render. if you want me to fix this, please <a href=\"https://wukko.me/contacts\">contact me</a>. it'd be useful if you provided the commit hash ({s}) along with recreation steps. thank you :D",
+    "brokenLink": "{s} is supported, but something is wrong with your link. maybe you didn't copy it fully?",
+    "noLink": "i can't guess what you want to download! please give me a link.",
+    "noRender": "something went wrong and page couldn't render. if you want me to fix this, please <a href=\"https://wukko.me/contacts\">contact me</a>. it'd be useful if you provided the commit hash ({s}) along with recreation steps. thank you :D",
     "rateLimit": "you're making way too many requests. calm down and try again in a few minutes.",
-    "youtubeFetch": "couldn't fetch metadata. check if your link is correct and try again.",
-    "youtubeLimit": "current length limit is {s} minutes. what you tried to download was longer than that. pick something else to download!",
-    "youtubeBroke": "something went wrong with info fetching. you can try a different format and resoltuion or just try again later.",
-    "corruptedVideo": "oddly enough the requested video is corrupted on its origin server. youtube does this sometimes because it's a hot pile of mess.",
-    "corruptedAudio": "oddly enough the requested audio is corrupted on its origin server. youtube does this sometimes because it's a hot pile of mess.",
+    "noFetch": "couldn't fetch metadata. check if your link is correct and try again.",
+    "lengthLimit": "current length limit is {s} minutes. what you tried to download was longer than that. pick something else to download!",
+    "errorFetch": "something went wrong with info fetching. you can try a different format and resoltuion or just try again later.",
+    "corruptedStream": "it seems like this download is corrupted. try again or try a different format and resolution.",
     "noInternet": "it seems like there's no internet or {appName} api is down. check your connection and try again.",
-    "liveVideo": "i can't download a live video. wait for stream to finish and try again.",
-    "nothingToDownload": "it seems like there's nothing to download. try another link!",
     "cantConnectToAPI": "i couldn't connect to {s} api. seems like either {s} is down or {appName} server ip got blocked. try again later.",
-    "noStreamID": "there's no such stream id.",
+    "nothingToDownload": "it seems like there's nothing to download. try another link!",
+    "liveVideo": "i can't download a live video. wait for stream to finish and try again.",
+    "noStreamID": "there's no such streamId.",
     "noType": "there's no such expected response type."
 }
\ No newline at end of file
diff --git a/src/i18n/en/settings.json b/src/i18n/en/settings.json
index 2b2e8daf..b40df8f3 100644
--- a/src/i18n/en/settings.json
+++ b/src/i18n/en/settings.json
@@ -16,6 +16,7 @@
     "qmid": "medium\n",
     "qlow": "low\n",
     "qlos": "lowest",
-    "qualityDesc": "all resolutions listed here are max values. if there's no video of preferred quality, closest one gets picked instead.",
-    "extra": "extra"
+    "qualityDesc": "if selected resolution isn't available, closest one gets picked instead.",
+    "extra": "extra",
+    "audioOnly": "audio only"
 }
\ No newline at end of file
diff --git a/src/i18n/en/desc.json b/src/i18n/en/strings.json
similarity index 96%
rename from src/i18n/en/desc.json
rename to src/i18n/en/strings.json
index ea05092b..f487b87f 100644
--- a/src/i18n/en/desc.json
+++ b/src/i18n/en/strings.json
@@ -11,7 +11,7 @@
     "donateDm": "&gt;&gt; let me know if currency you want to donate isn't listed",
     "clickToCopy": "click to copy",
     "iosDownload": "you have to press and hold the download button and then select \"download video\" in appeared popup to save the video. this is required because you have an ios device.",
-    "normalDownload": "download button opens a new tab with requested video. you can disable this popup in settings.",
+    "normalDownload": "download button opens a new tab with requested file. you can disable this popup in settings.",
     "download": "download",
     "copy": "copy url",
     "open": "open",
diff --git a/src/i18n/ru/accessibility.json b/src/i18n/ru/accessibility.json
new file mode 100644
index 00000000..5534e131
--- /dev/null
+++ b/src/i18n/ru/accessibility.json
@@ -0,0 +1,11 @@
+{
+    "about": "Что за {appName}?",
+    "settings": "Открыть настройки",
+    "input": "Вставь ссылку сюда",
+    "download": "Кнопка скачивания",
+    "changelog": "Посмотреть последние изменения (на английском)",
+    "close": "Закрыть окно",
+    "alwaysVisibleButton": "Всегда оставлять кнопку скачивания на экране",
+    "downloadPopup": "Спрашивать что делать с загрузками",
+    "donate": "Пожертвования"
+}
\ No newline at end of file
diff --git a/src/i18n/ru/apiError.json b/src/i18n/ru/apiError.json
new file mode 100644
index 00000000..de0f171e
--- /dev/null
+++ b/src/i18n/ru/apiError.json
@@ -0,0 +1,18 @@
+{
+    "generic": "что-то пошло совсем не так и у меня не получилось ничего для тебя достать. ты можешь попробовать ещё раз, но если так и не получится, <a class=\"text-backdrop nowrap\" href=\"{repo}\">напиши об этом</a>.",
+    "notSupported": "этот сервис ещё не поддерживается или с твоей ссылкой что-то не так.",
+    "brokenLink": "{s} поддерживается, но с твоей ссылкой что-то не так. может быть ты её не полностью скопировал?",
+    "noLink": "я не могу угадать что ты хочешь скачать. попробуй в следующий раз вставить ссылку.",
+    "noRender": "что-то пошло не так и у меня не получилось срендерить страницу. если это что-то критичное, пожалуйста, <a href=\"https://wukko.me/contacts\">напиши мне об этом</a>. приложи хэш текущего коммита ({s}) с действиями для получения ошибки. можно на русском языке. спасибо :)",
+    "rateLimit": "ты делаешь слишком много запросов. успокойся и попробуй ещё раз через несколько минут.",
+    "noFetch": "мне не удалось получить информацию о твоей ссылке. проверь её и попробуй ещё раз.",
+    "lengthLimit": "твоё видео было длиннее чем {s} минуты. это превышает текущий лимит. скачай что-нибудь покороче, а не войну и мир.",
+    "errorFetch": "что-то пошло не так с получением данных о твоей ссылке. попробуй другой формат и разрешение. если не получится, то попробуй ещё раз чуть позже.",
+    "corruptedStream": "эта загрузка повреждена. попробуй ещё раз. если не получится, то попробуй другой формат и разрешение.",
+    "noInternet": "кажется нет подключения к интернету. а возможно лежу я, а не твой интернет. в любом случае, проверь подключение к интернету и попробуй ещё раз.",
+    "cantConnectToAPI": "не получилось подключится к серверу {s}. {s} либо лежит, либо меня добавили в чёрный список. попробуй ещё раз чуть позже.",
+    "nothingToDownload": "мне нечего скачать. попробуй другую ссылку!",
+    "liveVideo": "я не могу скачать прямой эфир. дождись окончания трансляции и попробуй ещё раз.",
+    "noStreamID": "нет такого streamId.",
+    "noType": "нет такого формата ответа от сервера."
+}
\ No newline at end of file
diff --git a/src/i18n/ru/settings.json b/src/i18n/ru/settings.json
new file mode 100644
index 00000000..55a30cfd
--- /dev/null
+++ b/src/i18n/ru/settings.json
@@ -0,0 +1,22 @@
+{
+    "appearance": "внешний вид",
+    "alwaysVisibleButton": "оставлять >> на экране",
+    "downloadPopupButton": "спрашивать что делать с загрузками",
+    "format": "формат загрузок",
+    "formatInfo": "выбирай webm если хочешь максимальное качество. webm обычно лучше чем mp4 в плане качества, но устройства на ios не могут их проигрывать без сторонних приложений. все загрузки \"только аудио\" всегда максимального качества.",
+    "theme": "тема",
+    "themeAuto": "авто",
+    "themeLight": "светлая",
+    "themeDark": "тёмная",
+    "misc": "ещё",
+    "general": "загрузки",
+    "quality": "качество",
+    "qmax": "макс",
+    "qhig": "высокое\n",
+    "qmid": "среднее\n",
+    "qlow": "низкое\n",
+    "qlos": "ужасное",
+    "qualityDesc": "если выбранное разрешение недоступно, то выбирается ближайшее.",
+    "extra": "ещё",
+    "audioOnly": "только аудио"
+}
\ No newline at end of file
diff --git a/src/i18n/ru/strings.json b/src/i18n/ru/strings.json
new file mode 100644
index 00000000..a75500b7
--- /dev/null
+++ b/src/i18n/ru/strings.json
@@ -0,0 +1,18 @@
+{
+    "input": "вставь ссылку сюда",
+    "aboutSummary": "{appName} — твой друг при скачивании видео с соц.сетей. никакой рекламы или трекеров. просто вставь ссылку и ты прекрасен.",
+    "embed": "сохраняй что хочешь без мороки и вторжения в личное пространство",
+    "supportedServices": "что поддерживается:",
+    "sourceCode": "&gt;&gt; сообщай о проблемах на github",
+    "popupBottom": "сделано с <3 ~ wukko",
+    "noScript": "{appName} использует javascript для обработки ссылок и интерактивного интерфейса. ты должен разрешить использование javascript чтобы пользоваться сайтом. тут нет никаких трекеров или рекламы, обещаю.",
+    "donationsSub": "сейчас намного сложнее платить за хостинг",
+    "donations": "я ненавижу крипто, но у меня нет возможности платить любым другим способом.",
+    "donateDm": "&gt;&gt; если нет подходящей валюты, или же ты из россии, то напиши мне",
+    "clickToCopy": "нажми чтобы скопировать",
+    "iosDownload": "так как у тебя устройство на ios, тебе нужно зажать кнопку \"скачать\" и выбрать что-то похожее на \"сохранить в галерею\" в появившемся окне.",
+    "normalDownload": "кнопка скачивания открывает новое окно с файлом. ты можешь отключить метод сохранения файла в настройках.",
+    "download": "скачать",
+    "copy": "скопировать ссылку",
+    "github": "&gt;&gt; посмотреть предыдущие изменения на github"
+}
\ No newline at end of file
diff --git a/src/i18n/ru/title.json b/src/i18n/ru/title.json
new file mode 100644
index 00000000..9ced5ff4
--- /dev/null
+++ b/src/i18n/ru/title.json
@@ -0,0 +1,9 @@
+{
+    "about": "что за {appName}?",
+    "settings": "настройки",
+    "error": "о нет",
+    "changelog": "что нового?",
+    "donate": "поддержи {appName}",
+    "download": "скачивание",
+    "pickDownload": "как сохранить?"
+}
\ No newline at end of file
diff --git a/src/modules/api.js b/src/modules/api.js
index 7de3f61d..5584beba 100644
--- a/src/modules/api.js
+++ b/src/modules/api.js
@@ -30,6 +30,6 @@ export async function getJSON(originalURL, ip, lang, format, quality) {
             return apiJSON(0, { t: errorUnsupported(lang) } )
         }
     } catch (e) {
-        return apiJSON(0, { t: loc(lang, 'apiError', 'generic') + loc(lang, 'apiError', 'letMeKnow') });
+        return apiJSON(0, { t: loc(lang, 'apiError', 'generic') });
     }
 }
\ No newline at end of file
diff --git a/src/modules/match.js b/src/modules/match.js
index 2abcca31..0eb4ebc3 100644
--- a/src/modules/match.js
+++ b/src/modules/match.js
@@ -34,7 +34,7 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
                         lang: lang
                     });
                     return (!r.error) ? apiJSON(2, {
-                        type: "render", urls: r.urls,
+                        type: "render", urls: r.urls, lang: lang,
                         service: host, ip: ip,
                         filename: r.filename,
                         salt: process.env.streamSalt, time: r.time
@@ -73,7 +73,7 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
                     let r = await reddit({
                         sub: patternMatch["sub"],
                         id: patternMatch["id"],
-                        title: patternMatch["title"]
+                        title: patternMatch["title"], lang: lang,
                     });
                     return (!r.error) ? apiJSON(2, {
                         type: "render", urls: r.urls,
diff --git a/src/modules/pageRender.js b/src/modules/pageRender.js
index 1ec3fc17..158f785d 100644
--- a/src/modules/pageRender.js
+++ b/src/modules/pageRender.js
@@ -17,7 +17,7 @@ let enabledServices = Object.keys(s).filter((p) => {
 
 let donate = ``
 for (let i in donations) {
-    donate += `<div class="subtitle">${i} (${loc("en", 'desc', 'clickToCopy').trim()})</div><div id="don-${i}" class="text-to-copy" onClick="copy('don-${i}')">${donations[i]}</div>`
+    donate += `<div class="subtitle">${i} (REPLACEME)</div><div id="don-${i}" class="text-to-copy" onClick="copy('don-${i}')">${donations[i]}</div>`
 }
 
 let com = getCommitInfo();
@@ -34,10 +34,10 @@ export default function(obj) {
 
         <meta property="og:url" content="${process.env.selfURL}" />
         <meta property="og:title" content="${appName}" />
-        <meta property="og:description" content="${loc(obj.lang, 'desc', 'embed')}" />
+        <meta property="og:description" content="${loc(obj.lang, 'strings', 'embed')}" />
         <meta property="og:image" content="${process.env.selfURL}icons/generic.png" />
         <meta name="title" content="${appName}" />
-        <meta name="description" content="${loc(obj.lang, 'desc', 'embed')}" />
+        <meta name="description" content="${loc(obj.lang, 'strings', 'embed')}" />
         <meta name="theme-color" content="#000000" />
         <meta name="twitter:card" content="summary" />
 
@@ -50,7 +50,7 @@ export default function(obj) {
         <link rel="stylesheet" href="cobalt.css" />
         <link rel="stylesheet" href="fonts/notosansmono/notosansmono.css" />
 
-        <noscript><div style="margin: 2rem;">${loc(obj.lang, 'desc', 'noScript')}</div></noscript>
+        <noscript><div style="margin: 2rem;">${loc(obj.lang, 'strings', 'noScript')}</div></noscript>
     </head>
     <body id="cobalt-body">
         <div id="popup-download" class="popup center box" style="visibility: hidden;">
@@ -62,11 +62,11 @@ export default function(obj) {
             <div id="theme-switcher" class="switch-container small-padding">
                 <div class="subtitle">${loc(obj.lang, 'title', 'pickDownload')}</div>
                 <div class="switches">
-                    <a id="pd-download" class="switch full space-right" target="_blank"">${loc(obj.lang, 'desc', 'download')}</a>
-                    <div id="pd-copy" class="switch full">${loc(obj.lang, 'desc', 'copy')}</div>
+                    <a id="pd-download" class="switch full space-right" target="_blank"">${loc(obj.lang, 'strings', 'download')}</a>
+                    <div id="pd-copy" class="switch full">${loc(obj.lang, 'strings', 'copy')}</div>
                 </div>
             </div>
-                <div id="desc" class="explanation about-padding">${isIOS ? loc(obj.lang, 'desc', 'iosDownload') : loc(obj.lang, 'desc', 'normalDownload')}</div>
+                <div id="desc" class="explanation about-padding">${isIOS ? loc(obj.lang, 'strings', 'iosDownload') : loc(obj.lang, 'strings', 'normalDownload')}</div>
             </div>
         </div>
         <div id="popup-about" class="popup center box" style="visibility: hidden;">
@@ -75,12 +75,12 @@ export default function(obj) {
                 <div id="title" class="popup-title">${loc(obj.lang, 'title', 'about')}</div>
             </div>
             <div id="content" class="popup-content with-footer">
-                <div id="desc" class="popup-desc about-padding">${loc(obj.lang, 'desc', 'aboutSummary')}</div>
-                <div id="desc" class="popup-desc about-padding">${loc(obj.lang, 'desc', 'supportedServices')} ${enabledServices}.</div>
-                <div id="desc" class="popup-desc"><a class="text-backdrop" href="${repo}">${loc(obj.lang, 'desc', 'sourceCode')}</a></div>
+                <div id="desc" class="popup-desc about-padding">${loc(obj.lang, 'strings', 'aboutSummary')}</div>
+                <div id="desc" class="popup-desc about-padding">${loc(obj.lang, 'strings', 'supportedServices')} ${enabledServices}.</div>
+                <div id="desc" class="popup-desc"><a class="text-backdrop" href="${repo}">${loc(obj.lang, 'strings', 'sourceCode')}</a></div>
             </div>
             <div id="popup-footer" class="popup-footer">
-                <a id="popup-bottom" class="popup-footer-content" href="${authorInfo.link}">${loc(obj.lang, 'desc', 'popupBottom')}</a>
+                <a id="popup-bottom" class="popup-footer-content" href="${authorInfo.link}">${loc(obj.lang, 'strings', 'popupBottom')}</a>
             </div>
         </div>
         <div id="popup-changelog" class="popup center box" style="visibility: hidden;">
@@ -91,19 +91,19 @@ export default function(obj) {
             </div>
             <div id="content" class="popup-content">
                 <div id="desc" class="popup-desc about-padding">${com[1]}</div>
-                <div id="desc" class="popup-desc"><a class="text-backdrop" href="${repo}/commits">${loc(obj.lang, 'desc', 'github')}</a></div>
+                <div id="desc" class="popup-desc"><a class="text-backdrop" href="${repo}/commits">${loc(obj.lang, 'strings', 'github')}</a></div>
             </div>
         </div>
         <div id="popup-donate" class="popup scrollable center box" style="visibility: hidden;">
             <div id="popup-header" class="popup-header">
                 <button id="close" class="button mono" onclick="popup('donate', 0)" aria-label="${loc(obj.lang, 'accessibility', 'close')}">x</button>
                 <div id="title" class="popup-title">${loc(obj.lang, 'title', 'donate')}</div>
-                <div id="desc" class="little-subtitle">${loc(obj.lang, 'desc', 'donationsSub')}</div>
+                <div id="desc" class="little-subtitle">${loc(obj.lang, 'strings', 'donationsSub')}</div>
             </div>
             <div id="content" class="popup-content">
-                ${donate}
-                <div id="desc" class="explanation about-padding">${loc(obj.lang, 'desc', 'donations')}</div>
-                <div id="desc" class="popup-desc"><a class="text-backdrop" href="${authorInfo.contact}">${loc(obj.lang, 'desc', 'donateDm')}</a></div>
+                ${donate.replace(/REPLACEME/g, loc(obj.lang, 'strings', 'clickToCopy').trim())}
+                <div id="desc" class="explanation about-padding">${loc(obj.lang, 'strings', 'donations')}</div>
+                <div id="desc" class="popup-desc"><a class="text-backdrop" href="${authorInfo.contact}">${loc(obj.lang, 'strings', 'donateDm')}</a></div>
             </div>
         </div>
         <div id="popup-settings" class="popup scrollable center box" style="visibility: hidden;">
@@ -159,7 +159,7 @@ export default function(obj) {
                             <div class="switches">
                                 <div id="youtubeFormat-mp4" class="switch full" onclick="changeSwitcher('youtubeFormat', 'mp4', 1)">mp4</div>
                                 <div id="youtubeFormat-webm" class="switch" onclick="changeSwitcher('youtubeFormat', 'webm', 1)">webm</div>
-                                <div id="youtubeFormat-audio" class="switch full" onclick="changeSwitcher('youtubeFormat', 'audio', 1)">audio only</div>
+                                <div id="youtubeFormat-audio" class="switch full" onclick="changeSwitcher('youtubeFormat', 'audio', 1)">${loc(obj.lang, 'settings', 'audioOnly')}</div>
                             </div>
                             <div class="explanation">${loc(obj.lang, 'settings', 'formatInfo')}</div>
                         </div>
@@ -180,7 +180,7 @@ export default function(obj) {
         <div id="cobalt-main-box" class="center box" style="visibility: hidden;">
             <div id="logo-area">${appName}</div>
             <div id="download-area" class="mobile-center">
-                <input id="url-input-area" class="mono" type="text" autocorrect="off" maxlength="110" autocapitalize="off" placeholder="${loc(obj.lang, 'desc', 'input')}" aria-label="${loc(obj.lang, 'accessibility', 'input')}" oninput="button()">
+                <input id="url-input-area" class="mono" type="text" autocorrect="off" maxlength="110" autocapitalize="off" placeholder="${loc(obj.lang, 'strings', 'input')}" aria-label="${loc(obj.lang, 'accessibility', 'input')}" oninput="button()">
                 <input id="download-button" class="mono dontRead" onclick="download(document.getElementById('url-input-area').value)" type="submit" value="" disabled=true aria-label="${loc(obj.lang, 'accessibility', 'download')}">
             </div>
         </div>
@@ -197,6 +197,6 @@ export default function(obj) {
     <script type="text/javascript" src="cobalt.js"></script>
 </html>`;
     } catch (err) {
-        return `${loc('en', 'apiError', 'fatal', obj.hash)}`;
+        return `${loc('en', 'apiError', 'noRender', obj.hash)}`;
     }
 }
\ No newline at end of file
diff --git a/src/modules/services/bilibili.js b/src/modules/services/bilibili.js
index 65717d2f..99ff35e6 100644
--- a/src/modules/services/bilibili.js
+++ b/src/modules/services/bilibili.js
@@ -8,7 +8,7 @@ export default async function(obj) {
             headers: { "user-agent": genericUserAgent }
         });
         html.on('error', (err) => {
-            return { error: loc('en', 'apiError', 'youtubeFetch') };
+            return { error: loc(obj.lang, 'apiError', 'cantConnectToAPI', 'bilibili') };
         });
         html = html.body;
         if (html.includes('<script>window.__playinfo__=') && html.includes('"video_codecid"')) {
@@ -22,13 +22,13 @@ export default async function(obj) {
                 }).sort((a, b) => Number(b.bandwidth) - Number(a.bandwidth));
                 return { urls: [video[0]["baseUrl"], audio[0]["baseUrl"]], time: streamData.data.timelength, filename: `bilibili_${obj.id}_${video[0]["width"]}x${video[0]["height"]}.mp4` };
             } else {
-                return { error: loc('en', 'apiError', 'youtubeLimit', maxVideoDuration / 60000) };
+                return { error: loc(obj.lang, 'apiError', 'lengthLimit', maxVideoDuration / 60000) };
             }
         } else {
-            return { error: loc('en', 'apiError', 'youtubeFetch') };
+            return { error: loc(obj.lang, 'apiError', 'nothingToDownload') };
         }
     } catch (e) {
-        return { error: loc('en', 'apiError', 'youtubeFetch') };
+        return { error: loc(obj.lang, 'apiError', 'noFetch') };
     }
 }
 
diff --git a/src/modules/services/reddit.js b/src/modules/services/reddit.js
index f41cff78..a7986c31 100644
--- a/src/modules/services/reddit.js
+++ b/src/modules/services/reddit.js
@@ -9,9 +9,9 @@ export default async function(obj) {
         if ("reddit_video" in data["secure_media"] && data["secure_media"]["reddit_video"]["duration"] * 1000 < maxVideoDuration) {
             return { urls: [data["secure_media"]["reddit_video"]["fallback_url"].split('?')[0], `${data["secure_media"]["reddit_video"]["fallback_url"].split('_')[0]}_audio.mp4`], filename: `reddit_${data["secure_media"]["reddit_video"]["fallback_url"].split('/')[3]}.mp4` };
         } else {
-            return { error: loc('en', 'apiError', 'nothingToDownload') };
+            return { error: loc(obj.lang, 'apiError', 'nothingToDownload') };
         }
     } catch (err) {
-        return { error: loc("en", "apiError", "nothingToDownload") };
+        return { error: loc(obj.lang, 'apiError', 'noFetch') };
     }
 }
\ No newline at end of file
diff --git a/src/modules/services/twitter.js b/src/modules/services/twitter.js
index e96a5f6a..c2f2e25c 100644
--- a/src/modules/services/twitter.js
+++ b/src/modules/services/twitter.js
@@ -52,6 +52,6 @@ export default async function (obj) {
             }
         } else return parsbod;
     } catch (err) {
-        return { error: loc("en", "apiError", "youtubeBroke") };
+        return { error: loc("en", "apiError", "errorFetch") };
     }
 }
\ No newline at end of file
diff --git a/src/modules/services/vk.js b/src/modules/services/vk.js
index 9247d44b..1306ec26 100644
--- a/src/modules/services/vk.js
+++ b/src/modules/services/vk.js
@@ -30,18 +30,18 @@ export default async function(obj) {
                     if (selectedQuality in js["player"]["params"][0]) {
                         return { url: js["player"]["params"][0][selectedQuality].replace(`type=${maxQuality}`, `type=${services.vk.quality_match[userQuality]}`), filename: `vk_${js["player"]["params"][0][selectedQuality].split("id=")[1]}_${attr['width']}x${attr['height']}.mp4` };
                     } else {
-                        return { error: loc('en', 'apiError', 'nothingToDownload') };
+                        return { error: loc(obj.lang, 'apiError', 'nothingToDownload') };
                     }
                 } else {
-                    return { error: loc('en', 'apiError', 'youtubeLimit', maxVideoDuration / 60000) };
+                    return { error: loc(obj.lang, 'apiError', 'lengthLimit', maxVideoDuration / 60000) };
                 }
             } else {
-                return { error: loc('en', 'apiError', 'liveVideo') };
+                return { error: loc(obj.lang, 'apiError', 'liveVideo') };
             }
         } else {
-            return { error: loc('en', 'apiError', 'nothingToDownload') };
+            return { error: loc(obj.lang, 'apiError', 'nothingToDownload') };
         }
     } catch (err) {
-        return { error: loc('en', 'apiError', 'youtubeFetch') };
+        return { error: loc(obj.lang, 'apiError', 'errorFetch') };
     }
 }
\ No newline at end of file
diff --git a/src/modules/services/youtube.js b/src/modules/services/youtube.js
index b3fbce26..31a448e8 100644
--- a/src/modules/services/youtube.js
+++ b/src/modules/services/youtube.js
@@ -48,7 +48,7 @@ export default async function (obj) {
                             filename: `youtube_${obj.id}_${videoMatch[0]["width"]}x${videoMatch[0]["height"]}.${obj.format}` };
                             }
                         } else {
-                            return { error: loc('en', 'apiError', 'youtubeBroke') };
+                            return { error: loc('en', 'apiError', 'errorFetch') };
                         }
                     } else if (!obj.isAudioOnly) {
                         return { type: "render", urls: [video[0]["url"], audio[0]["url"]], time: video[0]["approxDurationMs"],
@@ -56,10 +56,10 @@ export default async function (obj) {
                     } else if (audio.length > 0) {
                         return { type: "render", isAudioOnly: true, urls: [audio[0]["url"]], filename: `youtube_${obj.id}_${audio[0]["audioBitrate"]}kbps.opus` };
                     } else {
-                        return { error: loc('en', 'apiError', 'youtubeBroke') };
+                        return { error: loc('en', 'apiError', 'errorFetch') };
                     }
                 } else {
-                    return { error: loc('en', 'apiError', 'youtubeLimit', maxVideoDuration / 60000) };
+                    return { error: loc('en', 'apiError', 'lengthLimit', maxVideoDuration / 60000) };
                 }
             } else {
                 return { error: loc('en', 'apiError', 'liveVideo') };
diff --git a/src/modules/stream/types.js b/src/modules/stream/types.js
index 42551125..d2b6f8e3 100644
--- a/src/modules/stream/types.js
+++ b/src/modules/stream/types.js
@@ -68,7 +68,7 @@ export async function streamLiveRender(streamInfo, res) {
                 ffmpegProcess.kill();
             });
         } else {
-            res.status(400).json({ status: "error", text: loc('en', 'apiError', 'corruptedVideo') });
+            res.status(400).json({ status: "error", text: loc('en', 'apiError', 'corruptedStream') });
         }
     } catch (e) {
         internalError(res);
diff --git a/src/modules/sub/errors.js b/src/modules/sub/errors.js
index 7a250f46..33964cc0 100644
--- a/src/modules/sub/errors.js
+++ b/src/modules/sub/errors.js
@@ -4,8 +4,8 @@ export function internalError(res) {
     res.status(501).json({ status: "error", text: "Internal Server Error" });
 }
 export function errorUnsupported(lang) {
-    return loc(lang, 'apiError', 'notSupported') + loc(lang, 'apiError', 'letMeKnow');
+    return loc(lang, 'apiError', 'notSupported');
 }
 export function genericError(lang, host) {
-    return loc(lang, 'apiError', 'brokenLink', host) + loc(lang, 'apiError', 'letMeKnow');
+    return loc(lang, 'apiError', 'brokenLink', host);
 }
\ No newline at end of file