diff --git a/src/client/app/common/views/components/user-list.vue b/src/client/app/common/views/components/user-list.vue
index 3147fbe371..9fcb80f8ad 100644
--- a/src/client/app/common/views/components/user-list.vue
+++ b/src/client/app/common/views/components/user-list.vue
@@ -1,8 +1,11 @@
 <template>
 <ui-container :body-togglable="true">
 	<template slot="header"><slot></slot></template>
+
+	<mk-error v-if="!fetching && !inited" @retry="init()"/>
+
 	<div class="efvhhmdq" v-size="[{ lt: 500, class: 'narrow' }]">
-		<div class="user" v-for="user in users">
+		<div class="user" v-for="user in us">
 			<mk-avatar class="avatar" :user="user"/>
 			<div class="body">
 				<div class="name">
@@ -14,6 +17,9 @@
 				</div>
 			</div>
 		</div>
+		<button class="more" :class="{ fetching: fetchingMoreUsers }" v-if="cursor != null" @click="fetchMoreUsers()" :disabled="fetchingMoreUsers">
+			<template v-if="fetchingMoreUsers"><fa icon="spinner" pulse fixed-width/></template>{{ fetchingMoreUsers ? $t('@.loading') : $t('@.load-more') }}
+		</button>
 	</div>
 </ui-container>
 </template>
@@ -23,14 +29,56 @@ import Vue from 'vue';
 
 export default Vue.extend({
 	props: {
-		users: {
-			type: Array,
+		makePromise: {
 			required: true
 		},
 		iconOnly: {
 			type: Boolean,
 			default: false
 		}
+	},
+
+	data() {
+		return {
+			fetching: true,
+			fetchingMoreUsers: false,
+			us: [],
+			inited: false,
+			cursor: null
+		};
+	},
+
+	created() {
+		this.init();
+	},
+
+	methods: {
+		init() {
+			this.fetching = true;
+			this.makePromise().then(x => {
+				if (Array.isArray(x)) {
+					this.us = x;
+				} else {
+					this.us = x.users;
+					this.cursor = x.cursor;
+				}
+				this.inited = true;
+				this.fetching = false;
+			}, e => {
+				this.fetching = false;
+			});
+		},
+
+		fetchMoreUsers() {
+			this.fetchingMoreUsers = true;
+			this.makePromise(this.cursor).then(x => {
+				this.us = x.users;
+				this.cursor = x.cursor;
+				this.fetchingMoreUsers = false;
+			}, e => {
+				this.fetchingMoreUsers = false;
+			});
+		}
 	}
 });
 </script>
diff --git a/src/client/app/common/views/pages/explore.vue b/src/client/app/common/views/pages/explore.vue
index b1e28415d8..2740e0381d 100644
--- a/src/client/app/common/views/pages/explore.vue
+++ b/src/client/app/common/views/pages/explore.vue
@@ -1,12 +1,12 @@
 <template>
 <div>
-	<mk-user-list :users="verifiedUsers">
+	<mk-user-list :make-promise="verifiedUsers">
 		<span><fa :icon="faBookmark"/> {{ $t('verified-users') }}</span>
 	</mk-user-list>
-	<mk-user-list :users="popularUsers">
+	<mk-user-list :make-promise="popularUsers">
 		<span><fa :icon="faChartLine"/> {{ $t('popular-users') }}</span>
 	</mk-user-list>
-	<mk-user-list :users="recentlyUpdatedUsers">
+	<mk-user-list :make-promise="recentlyUpdatedUsers">
 		<span><fa :icon="faCommentAlt"/> {{ $t('recently-updated-users') }}</span>
 	</mk-user-list>
 </div>
@@ -23,40 +23,26 @@ export default Vue.extend({
 
 	data() {
 		return {
-			verifiedUsers: [],
-			popularUsers: [],
-			recentlyUpdatedUsers: [],
+			verifiedUsers: () => this.$root.api('users', {
+				state: 'verified',
+				origin: 'local',
+				sort: '+follower',
+				limit: 10
+			}),
+			popularUsers: () => this.$root.api('users', {
+				state: 'alive',
+				origin: 'local',
+				sort: '+follower',
+				limit: 10
+			}),
+			recentlyUpdatedUsers: () => this.$root.api('users', {
+				origin: 'local',
+				sort: '+updatedAt',
+				limit: 10
+			}),
 			faBookmark, faChartLine, faCommentAlt
 		};
 	},
-
-	created() {
-		this.$root.api('users', {
-			state: 'verified',
-			origin: 'local',
-			sort: '+follower',
-			limit: 10
-		}).then(users => {
-			this.verifiedUsers = users;
-		});
-
-		this.$root.api('users', {
-			state: 'alive',
-			origin: 'local',
-			sort: '+follower',
-			limit: 10
-		}).then(users => {
-			this.popularUsers = users;
-		});
-
-		this.$root.api('users', {
-			origin: 'local',
-			sort: '+updatedAt',
-			limit: 10
-		}).then(users => {
-			this.recentlyUpdatedUsers = users;
-		});
-	}
 });
 </script>