diff --git a/src/all/mangadex/build.gradle b/src/all/mangadex/build.gradle
index 0a924f5ff..04c99e6df 100644
--- a/src/all/mangadex/build.gradle
+++ b/src/all/mangadex/build.gradle
@@ -5,7 +5,7 @@ ext {
     extName = 'MangaDex'
     pkgNameSuffix = 'all.mangadex'
     extClass = '.MangaDexFactory'
-    extVersionCode = 106
+    extVersionCode = 107
     libVersion = '1.2'
     containsNsfw = true
 }
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MDConstants.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MDConstants.kt
index 2ce2b8ee5..b393eb788 100644
--- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MDConstants.kt
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MDConstants.kt
@@ -4,26 +4,27 @@ import java.text.SimpleDateFormat
 import java.util.Locale
 import java.util.TimeZone
 
-class MDConstants {
+object MDConstants {
 
-    companion object {
-        val uuidRegex =
-            Regex("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}")
+    val uuidRegex =
+        Regex("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}")
 
-        val mangaLimit = 25
-        val apiUrl = "https://api.mangadex.org"
-        val apiMangaUrl = "$apiUrl/manga"
-        val atHomePostUrl = "https://api.mangadex.network/report"
-        val whitespaceRegex = "\\s".toRegex()
+    val mangaLimit = 25
+    val apiUrl = "https://api.mangadex.org"
+    val apiMangaUrl = "$apiUrl/manga"
+    val atHomePostUrl = "https://api.mangadex.network/report"
+    val whitespaceRegex = "\\s".toRegex()
 
-        val dateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+SSS", Locale.US)
-            .apply { timeZone = TimeZone.getTimeZone("UTC") }
+    val tempCover = "https://i.imgur.com/6TrIues.jpg"
 
-        const val prefixIdSearch = "id:"
+    val dateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+SSS", Locale.US)
+        .apply { timeZone = TimeZone.getTimeZone("UTC") }
 
-        const val dataSaverPrefTitle = "Data saver"
-        const val dataSaverPref = "dataSaver"
+    const val prefixIdSearch = "id:"
 
-        const val mdAtHomeTokenLifespan = 10 * 60 * 1000
-    }
+    const val dataSaverPrefTitle = "Data saver"
+    const val dataSaverPrefSummary = "Enables smaller more compressed images"
+    const val dataSaverPref = "dataSaverV5"
+
+    const val mdAtHomeTokenLifespan = 10 * 60 * 1000
 }
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDex.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDex.kt
index 75bf9fd47..9dd3a82b4 100644
--- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDex.kt
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDex.kt
@@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.extension.all.mangadex
 import android.app.Application
 import android.content.SharedPreferences
 import android.util.Log
+import androidx.preference.CheckBoxPreference
+import androidx.preference.PreferenceScreen
 import com.github.salomonbrys.kotson.array
 import com.github.salomonbrys.kotson.get
 import com.github.salomonbrys.kotson.int
@@ -20,6 +22,7 @@ import eu.kanade.tachiyomi.source.model.SManga
 import eu.kanade.tachiyomi.source.online.HttpSource
 import okhttp3.CacheControl
 import okhttp3.Headers
+import okhttp3.HttpUrl.Companion.toHttpUrl
 import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.Request
 import okhttp3.Response
@@ -54,12 +57,14 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
     // POPULAR Manga Section
 
     override fun popularMangaRequest(page: Int): Request {
+        val url = MDConstants.apiMangaUrl.toHttpUrl().newBuilder()
+            .addQueryParameter("order[updatedAt]", "desc")
+            .addQueryParameter("limit", MDConstants.mangaLimit.toString())
+            .addQueryParameter("offset", helper.getMangaListOffset(page))
+            .build().toUrl().toString()
+
         return GET(
-            url = "${MDConstants.apiMangaUrl}?order[updatedAt]=desc&limit=${MDConstants.mangaLimit}&offset=${
-            helper.getMangaListOffset(
-                page
-            )
-            }",
+            url = url,
             headers = headers,
             cache = CacheControl.FORCE_NETWORK
         )
@@ -67,7 +72,11 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
 
     override fun popularMangaParse(response: Response): MangasPage {
         if (response.isSuccessful.not()) {
-            throw Exception("Error getting popular manga http code: ${response.code}")
+            throw Exception("HTTP ${response.code}")
+        }
+
+        if (response.code == 204) {
+            return MangasPage(emptyList(), false)
         }
 
         val mangaListResponse = JsonParser.parseString(response.body!!.string()).obj
@@ -92,7 +101,7 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
             return GET(url.toString(), headers, CacheControl.FORCE_NETWORK)
         }
 
-        val tempUrl = MDConstants.apiMangaUrl.toHttpUrlOrNull()!!.newBuilder()
+        val tempUrl = MDConstants.apiMangaUrl.toHttpUrl().newBuilder()
 
         tempUrl.apply {
             addQueryParameter("limit", MDConstants.mangaLimit.toString())
@@ -124,6 +133,7 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
     override fun mangaDetailsRequest(manga: SManga): Request {
         return GET("${baseUrl}${manga.url}", headers)
     }
+
     /**
      * get manga details url throws exception if the url is the old format so people migrate
      */
@@ -163,16 +173,20 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
     override fun chapterListParse(response: Response): List<SChapter> {
 
         if (response.isSuccessful.not()) {
-            throw Exception("Error getting chapter list http code: ${response.code}")
+            throw Exception("HTTP ${response.code}")
+        }
+        if (response.code == 204) {
+            return emptyList()
         }
         try {
             val chapterListResponse = JsonParser.parseString(response.body!!.string()).obj
 
-            val chapterListResults = chapterListResponse["results"].array.map { it.obj }.toMutableList()
+            val chapterListResults =
+                chapterListResponse["results"].array.map { it.obj }.toMutableList()
 
             val mangaId =
                 response.request.url.toString().substringBefore("/feed")
-                    .substringAfter(MDConstants.apiMangaUrl)
+                    .substringAfter("${MDConstants.apiMangaUrl}/")
 
             val limit = chapterListResponse["limit"].int
 
@@ -216,7 +230,7 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
         val host =
             helper.getMdAtHomeUrl(atHomeRequestUrl, client, headers, CacheControl.FORCE_NETWORK)
 
-        val usingDataSaver = preferences.getInt(MDConstants.dataSaverPref, 0) == 1
+        val usingDataSaver = preferences.getBoolean("${MDConstants.dataSaverPref}_$lang", false)
 
         // have to add the time, and url to the page because pages timeout within 30mins now
         val now = Date().time
@@ -240,22 +254,20 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
     override fun imageUrlParse(response: Response): String = ""
 
     // mangadex is mvp no settings yet
-    override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
-        val dataSaverPref = androidx.preference.ListPreference(screen.context).apply {
-            key = MDConstants.dataSaverPref
+    override fun setupPreferenceScreen(screen: PreferenceScreen) {
+
+        val dataSaverPref = CheckBoxPreference(screen.context).apply {
+            key = "${MDConstants.dataSaverPref}_$lang"
             title = MDConstants.dataSaverPrefTitle
-            entries = arrayOf("Disable", "Enable")
-            entryValues = arrayOf("0", "1")
-            summary = "%s"
-            setDefaultValue("0")
+            summary = MDConstants.dataSaverPrefSummary
+            setDefaultValue(false)
 
             setOnPreferenceChangeListener { _, newValue ->
-                val selected = newValue as String
-                val index = this.findIndexOfValue(selected)
-                preferences.edit().putInt(MDConstants.dataSaverPref, index).commit()
+                val checkValue = newValue as Boolean
+                preferences.edit().putBoolean("${MDConstants.dataSaverPref}_$lang", checkValue)
+                    .commit()
             }
         }
-
         screen.addPreference(dataSaverPref)
     }
 
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexFactory.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexFactory.kt
index 0129590a6..076db1106 100644
--- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexFactory.kt
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexFactory.kt
@@ -48,7 +48,6 @@ class MangaDexFactory : SourceFactory {
         MangaDexHebrew(),
         MangaDexHindi(),
         MangaDexNorwegian(),
-        MangaDexOther()
     )
 }
 
@@ -67,12 +66,12 @@ class MangaDexVietnamese : MangaDex("vi")
 class MangaDexGreek : MangaDex("el")
 class MangaDexBulgarian : MangaDex("bg")
 class MangaDexSpanishSpain : MangaDex("es")
-class MangaDexPortugueseBrazil : MangaDex("pt-BR")
+class MangaDexPortugueseBrazil : MangaDex("pt-br")
 class MangaDexPortuguesePortugal : MangaDex("pt")
 class MangaDexSwedish : MangaDex("sv")
 class MangaDexArabic : MangaDex("ar")
 class MangaDexDanish : MangaDex("da")
-class MangaDexChineseSimp : MangaDex("zh-Hans")
+class MangaDexChineseSimp : MangaDex("zh")
 class MangaDexBengali : MangaDex("bn")
 class MangaDexRomanian : MangaDex("ro")
 class MangaDexCzech : MangaDex("cs")
@@ -80,17 +79,16 @@ class MangaDexMongolian : MangaDex("mn")
 class MangaDexTurkish : MangaDex("tr")
 class MangaDexIndonesian : MangaDex("id")
 class MangaDexKorean : MangaDex("ko")
-class MangaDexSpanishLTAM : MangaDex("es-419")
+class MangaDexSpanishLTAM : MangaDex("es-la")
 class MangaDexPersian : MangaDex("fa")
 class MangaDexMalay : MangaDex("ms")
 class MangaDexThai : MangaDex("th")
 class MangaDexCatalan : MangaDex("ca")
-class MangaDexFilipino : MangaDex("fil")
-class MangaDexChineseTrad : MangaDex("zh-Hant")
+class MangaDexFilipino : MangaDex("fi")
+class MangaDexChineseTrad : MangaDex("zh-hk")
 class MangaDexUkrainian : MangaDex("uk")
 class MangaDexBurmese : MangaDex("my")
 class MangaDexLithuanian : MangaDex("lt")
 class MangaDexHebrew : MangaDex("he")
 class MangaDexHindi : MangaDex("hi")
 class MangaDexNorwegian : MangaDex("no")
-class MangaDexOther : MangaDex("other")
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexFilters.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexFilters.kt
index 0555568b3..d6ce6f98c 100644
--- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexFilters.kt
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexFilters.kt
@@ -65,6 +65,7 @@ class MangaDexFilters {
     internal class Tag(val id: String, name: String) : Filter.TriState(name)
     private class TagList(tags: List<Tag>) : Filter.Group<Tag>("Tags", tags)
 
+    // to get all tags from dex https://api.mangadex.org/manga/tag
     internal fun getTags() = listOf(
         Tag("391b0423-d847-456f-aff0-8b0cfc03066b", "Action"),
         Tag("f4122d1c-3b44-44d0-9936-ff7502c39ad3", "Adaptation"),
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexHelper.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexHelper.kt
index 450f20610..e09a505ce 100644
--- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexHelper.kt
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDexHelper.kt
@@ -18,6 +18,7 @@ import okhttp3.OkHttpClient
 import okhttp3.Request
 import org.jsoup.parser.Parser
 import java.util.Date
+import java.util.Locale
 
 class MangaDexHelper() {
 
@@ -29,15 +30,15 @@ class MangaDexHelper() {
     fun getUUIDFromUrl(url: String) = url.substringAfterLast("/")
 
     /**
-     * get the manga feed url
+     * get chapters for manga (aka manga/$id/feed endpoint)
      */
     fun getChapterEndpoint(mangaId: String, offset: Int, langCode: String) =
         "${MDConstants.apiMangaUrl}/$mangaId/feed?limit=500&offset=$offset&locales[]=$langCode"
 
     /**
-     * Check if the manga id is a valid uuid
+     * Check if the manga url is a valid uuid
      */
-    fun containsUuid(id: String) = id.contains(MDConstants.uuidRegex)
+    fun containsUuid(url: String) = url.contains(MDConstants.uuidRegex)
 
     /**
      * Get the manga offset pages are 1 based, so subtract 1
@@ -130,7 +131,7 @@ class MangaDexHelper() {
         return SManga.create().apply {
             url = "/manga/$dexId"
             title = cleanString(attr["title"]["en"].string)
-            thumbnail_url = ""
+            thumbnail_url = MDConstants.tempCover
         }
     }
 
@@ -145,9 +146,9 @@ class MangaDexHelper() {
 
             // things that will go with the genre tags but aren't actually genre
             val nonGenres = listOf(
-                attr["contentRating"].nullString,
-                attr["originalLanguage"]?.nullString,
-                attr["publicationDemographic"]?.nullString
+                (attr["publicationDemographic"]?.nullString ?: "").capitalize(Locale.US),
+                ("Content rating: " + (attr["contentRating"].nullString ?: "").capitalize(Locale.US)),
+                Locale(attr["originalLanguage"].nullString ?: "").displayLanguage
             )
 
             // get authors ignore if they error, artists are labelled as authors currently
@@ -172,8 +173,8 @@ class MangaDexHelper() {
             val genreList = (
                 attr["tags"].array
                     .map { it["id"].string }
-                    .map { dexTag ->
-                        tags.firstOrNull { it.name.equals(dexTag, true) }
+                    .map { dexId ->
+                        tags.firstOrNull { it.id == dexId }
                     }.map { it?.name } +
                     nonGenres
                 )
@@ -185,7 +186,7 @@ class MangaDexHelper() {
                 description = cleanString(attr["description"]["en"].string)
                 author = authors.joinToString(", ")
                 status = getPublicationStatus(attr["publicationDemographic"].nullString)
-                thumbnail_url = ""
+                thumbnail_url = MDConstants.tempCover
                 genre = genreList.joinToString(", ")
             }
         } catch (e: Exception) {