diff --git a/public/src/client/popular.js b/public/src/client/popular.js
index f6af68cc22..f1ab3a5332 100644
--- a/public/src/client/popular.js
+++ b/public/src/client/popular.js
@@ -18,11 +18,12 @@ define('forum/popular', ['forum/recent', 'components', 'forum/infinitescroll'],
 		if (direction < 0 || !$('[component="category"]').length) {
 			return;
 		}
-
+		var query = utils.params();
 		infinitescroll.loadMore('topics.loadMorePopularTopics', {
 			after: $('[component="category"]').attr('data-nextstart'),
 			count: config.topicsPerPage,
-			cid: utils.params().cid,
+			cid: query.cid,
+			query: query,
 			term: ajaxify.data.selectedTerm.term,
 			filter: ajaxify.data.selectedFilter.filter,
 		}, function (data, done) {
diff --git a/public/src/client/recent.js b/public/src/client/recent.js
index 72eb7dd9ce..0f525a888c 100644
--- a/public/src/client/recent.js
+++ b/public/src/client/recent.js
@@ -202,11 +202,13 @@ define('forum/recent', ['forum/infinitescroll', 'components', 'handleBack'], fun
 
 	function loadTopicsAfter(after, direction, callback) {
 		callback = callback || function () {};
+		var query = utils.params();
 		infinitescroll.loadMore('topics.loadMoreRecentTopics', {
 			after: after,
 			direction: direction,
 			count: config.topicsPerPage,
-			cid: utils.params().cid,
+			cid: query.cid,
+			query: query,
 			filter: ajaxify.data.selectedFilter.filter,
 			set: $('[component="category"]').attr('data-set') ? $('[component="category"]').attr('data-set') : 'topics:recent',
 		}, function (data, done) {
diff --git a/public/src/client/top.js b/public/src/client/top.js
index 95e2cfdf44..18bc66558a 100644
--- a/public/src/client/top.js
+++ b/public/src/client/top.js
@@ -31,11 +31,12 @@ define('forum/top', ['forum/recent', 'forum/infinitescroll'], function (recent,
 		if (direction < 0 || !$('[component="category"]').length) {
 			return;
 		}
-
+		var query = utils.params();
 		infinitescroll.loadMore('topics.loadMoreTopTopics', {
 			after: $('[component="category"]').attr('data-nextstart'),
 			count: config.topicsPerPage,
-			cid: utils.params().cid,
+			cid: query.cid,
+			query: query,
 			term: ajaxify.data.selectedTerm.term,
 			filter: ajaxify.data.selectedFilter.filter,
 		}, function (data, done) {
diff --git a/public/src/client/unread.js b/public/src/client/unread.js
index 1f1c821ae6..e1824ff37a 100644
--- a/public/src/client/unread.js
+++ b/public/src/client/unread.js
@@ -90,11 +90,12 @@ define('forum/unread', ['forum/recent', 'topicSelect', 'forum/infinitescroll', '
 			if (direction < 0 || !$('[component="category"]').length) {
 				return;
 			}
-
+			var query = utils.params();
 			infinitescroll.loadMore('topics.loadMoreUnreadTopics', {
 				after: $('[component="category"]').attr('data-nextstart'),
 				count: config.topicsPerPage,
-				cid: utils.params().cid,
+				cid: query.cid,
+				query: query,
 				filter: ajaxify.data.selectedFilter.filter,
 			}, function (data, done) {
 				if (data.topics && data.topics.length) {
diff --git a/src/controllers/recent.js b/src/controllers/recent.js
index 727746a567..b4d56e523d 100644
--- a/src/controllers/recent.js
+++ b/src/controllers/recent.js
@@ -71,6 +71,7 @@ recentController.getData = function (req, url, sort, callback) {
 				filter: filter,
 				term: term,
 				sort: sort,
+				query: req.query,
 			}, next);
 		},
 		function (data, next) {
diff --git a/src/socket.io/topics/infinitescroll.js b/src/socket.io/topics/infinitescroll.js
index 8157656fe2..e2c87f3319 100644
--- a/src/socket.io/topics/infinitescroll.js
+++ b/src/socket.io/topics/infinitescroll.js
@@ -115,18 +115,21 @@ module.exports = function (SocketTopics) {
 		var stop = start + Math.max(0, itemsPerPage - 1);
 		start = Math.max(0, start);
 		stop = Math.max(0, stop);
-		if (sort === 'unread') {
-			return topics.getUnreadTopics({ cid: data.cid, uid: uid, start: start, stop: stop, filter: data.filter }, callback);
-		}
-		topics.getSortedTopics({
-			cids: data.cid,
+		const params = {
 			uid: uid,
 			start: start,
 			stop: stop,
 			filter: data.filter,
-			sort: sort,
-			term: data.term,
-		}, callback);
+			query: data.query,
+		};
+		if (sort === 'unread') {
+			params.cid = data.cid;
+			return topics.getUnreadTopics(params, callback);
+		}
+		params.cids = data.cid;
+		params.sort = sort;
+		params.term = data.term;
+		topics.getSortedTopics(params, callback);
 	}
 
 	SocketTopics.loadMoreFromSet = function (socket, data, callback) {
diff --git a/src/topics/sorted.js b/src/topics/sorted.js
index 5748f34551..1545608f8f 100644
--- a/src/topics/sorted.js
+++ b/src/topics/sorted.js
@@ -7,6 +7,7 @@ var db = require('../database');
 var privileges = require('../privileges');
 var user = require('../user');
 var meta = require('../meta');
+var plugins = require('../plugins');
 
 module.exports = function (Topics) {
 	Topics.getSortedTopics = function (params, callback) {
@@ -18,6 +19,7 @@ module.exports = function (Topics) {
 
 		params.term = params.term || 'alltime';
 		params.sort = params.sort || 'recent';
+		params.query = params.query || {};
 		if (params.hasOwnProperty('cids') && params.cids && !Array.isArray(params.cids)) {
 			params.cids = [params.cids];
 		}
@@ -70,7 +72,7 @@ module.exports = function (Topics) {
 				}
 			},
 			function (tids, next) {
-				filterTids(tids, params.uid, params.filter, params.cids, next);
+				filterTids(tids, params, next);
 			},
 		], callback);
 	}
@@ -113,7 +115,10 @@ module.exports = function (Topics) {
 		return parseInt(b.viewcount, 10) - parseInt(a.viewcount, 10);
 	}
 
-	function filterTids(tids, uid, filter, cids, callback) {
+	function filterTids(tids, params, callback) {
+		const filter = params.filter;
+		const uid = params.uid;
+
 		async.waterfall([
 			function (next) {
 				if (filter === 'watched') {
@@ -153,16 +158,17 @@ module.exports = function (Topics) {
 				});
 			},
 			function (results, next) {
-				cids = cids && cids.map(String);
+				const cids = params.cids && params.cids.map(String);
 				tids = results.topicData.filter(function (topic) {
 					if (topic && topic.cid) {
 						return !results.ignoredCids.includes(topic.cid.toString()) && (!cids || (cids.length && cids.includes(topic.cid.toString())));
 					}
 					return false;
-				}).map(function (topic) {
-					return topic.tid;
-				});
-				next(null, tids);
+				}).map(topic => topic.tid);
+				plugins.fireHook('filter:topics.filterSortedTids', { tids: tids, params: params }, next);
+			},
+			function (data, next) {
+				next(null, data && data.tids);
 			},
 		], callback);
 	}