diff --git a/src/fr/japanread/build.gradle b/src/fr/japanread/build.gradle
index df4a11a1d..96780723e 100644
--- a/src/fr/japanread/build.gradle
+++ b/src/fr/japanread/build.gradle
@@ -5,7 +5,7 @@ ext {
     extName = 'Japanread'
     pkgNameSuffix = 'fr.japanread'
     extClass = '.Japanread'
-    extVersionCode = 6
+    extVersionCode = 7
     libVersion = '1.2'
     containsNsfw = true
 }
diff --git a/src/fr/japanread/src/eu/kanade/tachiyomi/extension/fr/japanread/Japanread.kt b/src/fr/japanread/src/eu/kanade/tachiyomi/extension/fr/japanread/Japanread.kt
index cf6c2ed78..a5756df67 100644
--- a/src/fr/japanread/src/eu/kanade/tachiyomi/extension/fr/japanread/Japanread.kt
+++ b/src/fr/japanread/src/eu/kanade/tachiyomi/extension/fr/japanread/Japanread.kt
@@ -1,9 +1,11 @@
 package eu.kanade.tachiyomi.extension.fr.japanread
 
+import android.net.Uri
 import com.github.salomonbrys.kotson.string
 import com.google.gson.JsonParser
 import eu.kanade.tachiyomi.network.GET
 import eu.kanade.tachiyomi.network.asObservableSuccess
+import eu.kanade.tachiyomi.source.model.Filter
 import eu.kanade.tachiyomi.source.model.FilterList
 import eu.kanade.tachiyomi.source.model.Page
 import eu.kanade.tachiyomi.source.model.SChapter
@@ -35,6 +37,7 @@ class Japanread : ParsedHttpSource() {
             thumbnail_url = element.select("img").attr("src").replace("manga_medium", "manga_large")
         }
     }
+
     private fun mangaListSelector() = "div#manga-container div.col-lg-6"
     private fun mangaListNextPageSelector() = "a[rel=next]"
 
@@ -42,6 +45,7 @@ class Japanread : ParsedHttpSource() {
     override fun popularMangaRequest(page: Int): Request {
         return GET("$baseUrl/manga-list?sortType=9&page=$page", headers)
     }
+
     override fun popularMangaSelector() = mangaListSelector()
     override fun popularMangaFromElement(element: Element) = mangaListFromElement(element)
     override fun popularMangaNextPageSelector() = mangaListNextPageSelector()
@@ -50,14 +54,32 @@ class Japanread : ParsedHttpSource() {
     override fun latestUpdatesRequest(page: Int): Request {
         return GET("$baseUrl/manga-list?sortType=0&page=$page", headers)
     }
+
     override fun latestUpdatesSelector() = mangaListSelector()
     override fun latestUpdatesFromElement(element: Element) = mangaListFromElement(element)
     override fun latestUpdatesNextPageSelector() = mangaListNextPageSelector()
 
     // Search
     override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
-        return GET("$baseUrl/search?q=$query&page=$page")
+        // If there is any search text, use text search, otherwise use filter search
+        val uri = if (query.isNotBlank()) {
+            Uri.parse("$baseUrl/search")
+                .buildUpon()
+                .appendQueryParameter("q", query)
+        } else {
+            val uri = Uri.parse("$baseUrl/manga-list").buildUpon()
+            // Append uri filters
+            filters.forEach {
+                if (it is UriFilter)
+                    it.addToUri(uri)
+            }
+            uri
+        }
+        // Append page number
+        uri.appendQueryParameter("page", page.toString())
+        return GET(uri.toString())
     }
+
     override fun searchMangaSelector() = mangaListSelector()
     override fun searchMangaFromElement(element: Element) = mangaListFromElement(element)
     override fun searchMangaNextPageSelector() = mangaListNextPageSelector()
@@ -107,6 +129,7 @@ class Japanread : ParsedHttpSource() {
     }
 
     override fun chapterListSelector() = "#chapters div[data-row=chapter]"
+
     override fun chapterFromElement(element: Element): SChapter {
         return SChapter.create().apply {
             name = element.select("div.col-lg-5 a").text()
@@ -204,7 +227,7 @@ class Japanread : ParsedHttpSource() {
         val apiResponse = client.newCall(GET("$baseUrl/api/?id=$chapterId&type=chapter", apiHeaders())).execute()
 
         val jsonData = apiResponse.body!!.string()
-        val json = JsonParser().parse(jsonData).asJsonObject
+        val json = JsonParser.parseString(jsonData).asJsonObject
 
         val baseImagesUrl = json["baseImagesUrl"].string
 
@@ -215,7 +238,125 @@ class Japanread : ParsedHttpSource() {
     }
 
     override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not Used")
+
     override fun imageRequest(page: Page): Request {
         return GET(page.imageUrl!!, headers)
     }
+
+    // Filters
+    override fun getFilterList() = FilterList(
+        SortFilter(),
+        TypeFilter(),
+        StatusFilter(),
+        GenreFilter()
+    )
+
+    private class SortFilter : UriSelectFilter(
+        "Tri",
+        "sortType",
+        arrayOf(
+            Pair("9", "Les + vus"),
+            Pair("7", "Les mieux notés"),
+            Pair("2", "A - Z"),
+            Pair("5", "Les + commentés"),
+            Pair("0", "Les + récents"),
+        ),
+        firstIsUnspecified = false,
+    )
+
+    private class TypeFilter : UriSelectFilter(
+        "Type",
+        "withTypes",
+        arrayOf(
+            Pair("0", "Tous"),
+            Pair("2", "Manga"),
+            Pair("3", "Manhwa"),
+            Pair("4", "Manhua"),
+            Pair("5", "Novel"),
+            Pair("6", "Doujinshi")
+        )
+    )
+
+    private class StatusFilter : UriSelectFilter(
+        "Statut",
+        "status",
+        arrayOf(
+            Pair("0", "Tous"),
+            Pair("1", "En cours"),
+            Pair("2", "Terminé")
+        )
+    )
+
+    private class GenreFilter : UriSelectFilter(
+        "Genre",
+        "withCategories",
+        arrayOf(
+            Pair("0", "Tous"),
+            Pair("1", "Action"),
+            Pair("27", "Adulte"),
+            Pair("20", "Amitié"),
+            Pair("21", "Amour"),
+            Pair("7", "Arts martiaux"),
+            Pair("3", "Aventure"),
+            Pair("6", "Combat"),
+            Pair("5", "Comédie"),
+            Pair("4", "Drame"),
+            Pair("12", "Ecchi"),
+            Pair("16", "Fantastique"),
+            Pair("29", "Gender Bender"),
+            Pair("8", "Guerre"),
+            Pair("22", "Harem"),
+            Pair("23", "Hentai"),
+            Pair("15", "Historique"),
+            Pair("19", "Horreur"),
+            Pair("13", "Josei"),
+            Pair("30", "Mature"),
+            Pair("18", "Mecha"),
+            Pair("32", "One-shot"),
+            Pair("42", "Parodie"),
+            Pair("17", "Policier"),
+            Pair("25", "Science-fiction"),
+            Pair("31", "Seinen"),
+            Pair("10", "Shojo"),
+            Pair("26", "Shojo Ai"),
+            Pair("2", "Shonen"),
+            Pair("35", "Shonen Ai"),
+            Pair("37", "Smut"),
+            Pair("14", "Sports"),
+            Pair("38", "Surnaturel"),
+            Pair("39", "Tragédie"),
+            Pair("36", "Tranches de vie"),
+            Pair("34", "Vie scolaire"),
+            Pair("24", "Yaoi"),
+            Pair("41", "Yuri"),
+        )
+    )
+
+    /**
+     * Class that creates a select filter. Each entry in the dropdown has a name and a display name.
+     * If an entry is selected it is appended as a query parameter onto the end of the URI.
+     * If `firstIsUnspecified` is set to true, if the first entry is selected, nothing will be appended on the the URI.
+     */
+    // vals: <name, display>
+    private open class UriSelectFilter(
+        displayName: String,
+        val uriParam: String,
+        val vals: Array<Pair<String, String>>,
+        val firstIsUnspecified: Boolean = true,
+        defaultValue: Int = 0
+    ) :
+        Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue),
+        UriFilter {
+        override fun addToUri(uri: Uri.Builder) {
+            if (state != 0 || !firstIsUnspecified)
+                uri.appendQueryParameter(uriParam, vals[state].first)
+        }
+    }
+
+    /**
+     * Represents a filter that is able to modify a URI.
+     */
+    private interface UriFilter {
+        fun addToUri(uri: Uri.Builder)
+    }
 }