diff --git a/lib-multisrc/mangabox/src/eu/kanade/tachiyomi/multisrc/mangabox/MangaBox.kt b/lib-multisrc/mangabox/src/eu/kanade/tachiyomi/multisrc/mangabox/MangaBox.kt
index 42aecad9f..df3f5165b 100644
--- a/lib-multisrc/mangabox/src/eu/kanade/tachiyomi/multisrc/mangabox/MangaBox.kt
+++ b/lib-multisrc/mangabox/src/eu/kanade/tachiyomi/multisrc/mangabox/MangaBox.kt
@@ -199,7 +199,7 @@ abstract class MangaBox(
 
     protected open val alternateChapterDateSelector = String()
 
-    private fun Element.selectDateFromElement(): Element {
+    protected fun Element.selectDateFromElement(): Element {
         val defaultChapterDateSelector = "span"
         return this.select(defaultChapterDateSelector).lastOrNull() ?: this.select(alternateChapterDateSelector).last()!!
     }
@@ -305,10 +305,11 @@ abstract class MangaBox(
         )
     }
 
-    private class KeywordFilter(vals: Array<Pair<String?, String>>) : UriPartFilter("Keyword search ", vals)
-    private class SortFilter(vals: Array<Pair<String?, String>>) : UriPartFilter("Order by", vals)
-    private class StatusFilter(vals: Array<Pair<String?, String>>) : UriPartFilter("Status", vals)
-    private class GenreFilter(vals: Array<Pair<String?, String>>) : UriPartFilter("Category", vals)
+    // Technically, only Sort, Status, and Genre need to be non-private for Mangakakalot and Manganato, but I'll include Keyword to make it uniform.
+    protected class KeywordFilter(vals: Array<Pair<String?, String>>) : UriPartFilter("Keyword search ", vals)
+    protected class SortFilter(vals: Array<Pair<String?, String>>) : UriPartFilter("Order by", vals)
+    protected class StatusFilter(vals: Array<Pair<String?, String>>) : UriPartFilter("Status", vals)
+    protected class GenreFilter(vals: Array<Pair<String?, String>>) : UriPartFilter("Category", vals)
 
     // For advanced search, specifically tri-state genres
     private class AdvGenreFilter(vals: List<AdvGenre>) : Filter.Group<AdvGenre>("Category", vals)
diff --git a/src/en/mangakakalot/build.gradle b/src/en/mangakakalot/build.gradle
index 18523a010..41d9788ca 100644
--- a/src/en/mangakakalot/build.gradle
+++ b/src/en/mangakakalot/build.gradle
@@ -2,8 +2,8 @@ ext {
     extName = 'Mangakakalot'
     extClass = '.Mangakakalot'
     themePkg = 'mangabox'
-    baseUrl = 'https://mangakakalot.com'
-    overrideVersionCode = 3
+    baseUrl = 'https://www.mangakakalot.gg'
+    overrideVersionCode = 4
 }
 
 apply from: "$rootDir/common.gradle"
diff --git a/src/en/mangakakalot/src/eu/kanade/tachiyomi/extension/en/mangakakalot/Mangakakalot.kt b/src/en/mangakakalot/src/eu/kanade/tachiyomi/extension/en/mangakakalot/Mangakakalot.kt
index 93ebc819e..ab998e042 100644
--- a/src/en/mangakakalot/src/eu/kanade/tachiyomi/extension/en/mangakakalot/Mangakakalot.kt
+++ b/src/en/mangakakalot/src/eu/kanade/tachiyomi/extension/en/mangakakalot/Mangakakalot.kt
@@ -1,10 +1,115 @@
 package eu.kanade.tachiyomi.extension.en.mangakakalot
 
 import eu.kanade.tachiyomi.multisrc.mangabox.MangaBox
+import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.FilterList
+import eu.kanade.tachiyomi.source.model.Page
+import eu.kanade.tachiyomi.source.model.SChapter
 import okhttp3.Headers
+import okhttp3.HttpUrl.Companion.toHttpUrl
+import okhttp3.Request
+import org.jsoup.nodes.Element
+import java.text.ParseException
+import java.text.SimpleDateFormat
+import java.util.Locale
 
-class Mangakakalot : MangaBox("Mangakakalot", "https://mangakakalot.com", "en") {
-    override fun headersBuilder(): Headers.Builder = super.headersBuilder().set("Referer", "https://manganato.com") // for covers
+class Mangakakalot : MangaBox("Mangakakalot", "https://www.mangakakalot.gg", "en") {
+    private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMM-dd-yyyy HH:mm", Locale.ENGLISH)
+
+    override fun headersBuilder(): Headers.Builder = super.headersBuilder().set("Referer", "$baseUrl/") // for covers
+    override val popularUrlPath = "manga-list/hot-manga?page="
+    override val latestUrlPath = "manga-list/latest-manga?page="
     override val simpleQueryPath = "search/story/"
     override fun searchMangaSelector() = "${super.searchMangaSelector()}, div.list-truyen-item-wrap"
+
+    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+        return if (query.isNotBlank() && getAdvancedGenreFilters().isEmpty()) {
+            val url = "$baseUrl/$simpleQueryPath".toHttpUrl().newBuilder()
+                .addPathSegment(normalizeSearchQuery(query))
+                .addQueryParameter("page", page.toString())
+                .build()
+
+            return GET(url, headers)
+        } else {
+            val url = "$baseUrl/genre".toHttpUrl().newBuilder()
+            url.addQueryParameter("page", page.toString())
+            filters.forEach { filter ->
+                when (filter) {
+                    is SortFilter -> url.addQueryParameter("type", filter.toUriPart())
+                    is StatusFilter -> url.addQueryParameter("state", filter.toUriPart())
+                    is GenreFilter -> url.addPathSegment(filter.toUriPart()!!)
+                    else -> {}
+                }
+            }
+
+            GET(url.build(), headers)
+        }
+    }
+
+    override fun chapterFromElement(element: Element): SChapter {
+        // parse on title attribute rather than the value
+        val dateUploadAttr: Long? = try {
+            dateFormat.parse(element.selectDateFromElement().attr("title"))?.time
+        } catch (e: ParseException) {
+            null
+        }
+
+        return super.chapterFromElement(element).apply {
+            date_upload = dateUploadAttr ?: date_upload
+        }
+    }
+
+    override val descriptionSelector = "div#contentBox"
+
+    override fun imageRequest(page: Page): Request {
+        return if (page.url.contains(baseUrl)) {
+            GET(page.imageUrl!!, headersBuilder().build())
+        } else { // Avoid 403 errors on non-migrated mangas
+            super.imageRequest(page)
+        }
+    }
+
+    override fun getGenreFilters(): Array<Pair<String?, String>> = arrayOf(
+        Pair("all", "ALL"),
+        Pair("action", "Action"),
+        Pair("adult", "Adult"),
+        Pair("adventure", "Adventure"),
+        Pair("comedy", "Comedy"),
+        Pair("cooking", "Cooking"),
+        Pair("doujinshi", "Doujinshi"),
+        Pair("drama", "Drama"),
+        Pair("ecchi", "Ecchi"),
+        Pair("fantasy", "Fantasy"),
+        Pair("gender-bender", "Gender bender"),
+        Pair("harem", "Harem"),
+        Pair("historical", "Historical"),
+        Pair("horror", "Horror"),
+        Pair("isekai", "Isekai"),
+        Pair("josei", "Josei"),
+        Pair("manhua", "Manhua"),
+        Pair("manhwa", "Manhwa"),
+        Pair("martial-arts", "Martial arts"),
+        Pair("mature", "Mature"),
+        Pair("mecha", "Mecha"),
+        Pair("medical", "Medical"),
+        Pair("mystery", "Mystery"),
+        Pair("one-shot", "One shot"),
+        Pair("psychological", "Psychological"),
+        Pair("romance", "Romance"),
+        Pair("school-life", "School life"),
+        Pair("sci-fi", "Sci fi"),
+        Pair("seinen", "Seinen"),
+        Pair("shoujo", "Shoujo"),
+        Pair("shoujo-ai", "Shoujo ai"),
+        Pair("shounen", "Shounen"),
+        Pair("shounen-ai", "Shounen ai"),
+        Pair("slice-of-life", "Slice of life"),
+        Pair("smut", "Smut"),
+        Pair("sports", "Sports"),
+        Pair("supernatural", "Supernatural"),
+        Pair("tragedy", "Tragedy"),
+        Pair("webtoons", "Webtoons"),
+        Pair("yaoi", "Yaoi"),
+        Pair("yuri", "Yuri"),
+    )
 }
diff --git a/src/en/manganelo/build.gradle b/src/en/manganelo/build.gradle
index d34b6c9a1..3eed9ffcd 100644
--- a/src/en/manganelo/build.gradle
+++ b/src/en/manganelo/build.gradle
@@ -2,8 +2,8 @@ ext {
     extName = 'Manganato'
     extClass = '.Manganato'
     themePkg = 'mangabox'
-    baseUrl = 'https://manganato.com'
-    overrideVersionCode = 2
+    baseUrl = 'https://www.natomanga.com'
+    overrideVersionCode = 3
 }
 
 apply from: "$rootDir/common.gradle"
diff --git a/src/en/manganelo/src/eu/kanade/tachiyomi/extension/en/manganelo/Manganato.kt b/src/en/manganelo/src/eu/kanade/tachiyomi/extension/en/manganelo/Manganato.kt
index 92c1e937b..4a877b629 100644
--- a/src/en/manganelo/src/eu/kanade/tachiyomi/extension/en/manganelo/Manganato.kt
+++ b/src/en/manganelo/src/eu/kanade/tachiyomi/extension/en/manganelo/Manganato.kt
@@ -2,20 +2,116 @@ package eu.kanade.tachiyomi.extension.en.manganelo
 
 import eu.kanade.tachiyomi.multisrc.mangabox.MangaBox
 import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.source.model.FilterList
+import eu.kanade.tachiyomi.source.model.Page
+import eu.kanade.tachiyomi.source.model.SChapter
+import okhttp3.Headers
+import okhttp3.HttpUrl.Companion.toHttpUrl
 import okhttp3.Request
+import org.jsoup.nodes.Element
+import java.text.ParseException
 import java.text.SimpleDateFormat
 import java.util.Locale
 
-class Manganato : MangaBox("Manganato", "https://manganato.com", "en", SimpleDateFormat("MMM dd,yy", Locale.ENGLISH)) {
+class Manganato : MangaBox("Manganato", "https://www.natomanga.com", "en") {
     override val id: Long = 1024627298672457456
 
-    // Nelo's date format is part of the base class
-    override fun popularMangaRequest(page: Int): Request = GET("$baseUrl/genre-all/$page?type=topview", headers)
-    override fun popularMangaSelector() = "div.content-genres-item"
-    override val latestUrlPath = "genre-all/"
+    private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMM-dd-yyyy HH:mm", Locale.ENGLISH)
+
+    override fun headersBuilder(): Headers.Builder = super.headersBuilder().set("Referer", "$baseUrl/") // for covers
+    override val popularUrlPath = "manga-list/hot-manga?page="
+    override val latestUrlPath = "manga-list/latest-manga?page="
     override val simpleQueryPath = "search/story/"
-    override fun searchMangaSelector() = "div.search-story-item, div.content-genres-item"
-    override fun getAdvancedGenreFilters(): List<AdvGenre> = getGenreFilters()
-        .drop(1)
-        .map { AdvGenre(it.first, it.second) }
+    override fun searchMangaSelector() = "${super.searchMangaSelector()}, div.list-truyen-item-wrap"
+
+    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
+        return if (query.isNotBlank() && getAdvancedGenreFilters().isEmpty()) {
+            val url = "$baseUrl/$simpleQueryPath".toHttpUrl().newBuilder()
+                .addPathSegment(normalizeSearchQuery(query))
+                .addQueryParameter("page", page.toString())
+                .build()
+
+            return GET(url, headers)
+        } else {
+            val url = "$baseUrl/genre".toHttpUrl().newBuilder()
+            url.addQueryParameter("page", page.toString())
+            filters.forEach { filter ->
+                when (filter) {
+                    is SortFilter -> url.addQueryParameter("type", filter.toUriPart())
+                    is StatusFilter -> url.addQueryParameter("state", filter.toUriPart())
+                    is GenreFilter -> url.addPathSegment(filter.toUriPart()!!)
+                    else -> {}
+                }
+            }
+
+            GET(url.build(), headers)
+        }
+    }
+
+    override fun chapterFromElement(element: Element): SChapter {
+        // parse on title attribute rather than the value
+        val dateUploadAttr: Long? = try {
+            dateFormat.parse(element.selectDateFromElement().attr("title"))?.time
+        } catch (e: ParseException) {
+            null
+        }
+
+        return super.chapterFromElement(element).apply {
+            date_upload = dateUploadAttr ?: date_upload
+        }
+    }
+
+    override val descriptionSelector = "div#contentBox"
+
+    override fun imageRequest(page: Page): Request {
+        return if (page.url.contains(baseUrl)) {
+            GET(page.imageUrl!!, headersBuilder().build())
+        } else { // Avoid 403 errors on non-migrated mangas
+            super.imageRequest(page)
+        }
+    }
+
+    override fun getGenreFilters(): Array<Pair<String?, String>> = arrayOf(
+        Pair("all", "ALL"),
+        Pair("action", "Action"),
+        Pair("adult", "Adult"),
+        Pair("adventure", "Adventure"),
+        Pair("comedy", "Comedy"),
+        Pair("cooking", "Cooking"),
+        Pair("doujinshi", "Doujinshi"),
+        Pair("drama", "Drama"),
+        Pair("ecchi", "Ecchi"),
+        Pair("fantasy", "Fantasy"),
+        Pair("gender-bender", "Gender bender"),
+        Pair("harem", "Harem"),
+        Pair("historical", "Historical"),
+        Pair("horror", "Horror"),
+        Pair("isekai", "Isekai"),
+        Pair("josei", "Josei"),
+        Pair("manhua", "Manhua"),
+        Pair("manhwa", "Manhwa"),
+        Pair("martial-arts", "Martial arts"),
+        Pair("mature", "Mature"),
+        Pair("mecha", "Mecha"),
+        Pair("medical", "Medical"),
+        Pair("mystery", "Mystery"),
+        Pair("one-shot", "One shot"),
+        Pair("psychological", "Psychological"),
+        Pair("romance", "Romance"),
+        Pair("school-life", "School life"),
+        Pair("sci-fi", "Sci fi"),
+        Pair("seinen", "Seinen"),
+        Pair("shoujo", "Shoujo"),
+        Pair("shoujo-ai", "Shoujo ai"),
+        Pair("shounen", "Shounen"),
+        Pair("shounen-ai", "Shounen ai"),
+        Pair("slice-of-life", "Slice of life"),
+        Pair("smut", "Smut"),
+        Pair("sports", "Sports"),
+        Pair("supernatural", "Supernatural"),
+        Pair("tragedy", "Tragedy"),
+        Pair("webtoons", "Webtoons"),
+        Pair("yaoi", "Yaoi"),
+        Pair("yuri", "Yuri"),
+    )
 }