diff --git a/CHANGELOG.md b/CHANGELOG.md
index 24c5a77e6f..7207544620 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@ ChangeLog
 unreleased
 -------------------
 ### ✨Improvements
+* 投稿詳細ページで前後の投稿を見れるように
 * 自分のfollowersノートはRenoteできるように
 * フォロー申請ページの調整
 * 壁紙設定の強化
diff --git a/src/client/components/notes.vue b/src/client/components/notes.vue
index be8f68e3a6..487dff16a8 100644
--- a/src/client/components/notes.vue
+++ b/src/client/components/notes.vue
@@ -7,16 +7,23 @@
 
 	<mk-error v-if="error" @retry="init()"/>
 
-	<x-list ref="notes" class="notes" :items="notes" v-slot="{ item: note }">
-		<x-note :note="note" :detail="detail" :key="note.id"/>
-	</x-list>
-
-	<footer class="more" v-if="more">
+	<div class="more" v-if="more && reversed" style="margin-bottom: var(--margin);">
 		<mk-button class="button" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" @click="fetchMore()" primary>
 			<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
 			<template v-if="moreFetching"><mk-loading inline/></template>
 		</mk-button>
-	</footer>
+	</div>
+
+	<x-list ref="notes" class="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed">
+		<x-note :note="note" :detail="detail" :key="note.id"/>
+	</x-list>
+
+	<div class="more" v-if="more && !reversed" style="margin-top: var(--margin);">
+		<mk-button class="button" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }" @click="fetchMore()" primary>
+			<template v-if="!moreFetching">{{ $t('loadMore') }}</template>
+			<template v-if="moreFetching"><mk-loading inline/></template>
+		</mk-button>
+	</div>
 </div>
 </template>
 
@@ -67,6 +74,10 @@ export default Vue.extend({
 		notes(): any[] {
 			return this.extract ? this.extract(this.items) : this.items;
 		},
+
+		reversed(): boolean {
+			return this.pagination.reversed;
+		}
 	},
 
 	methods: {
@@ -92,14 +103,14 @@ export default Vue.extend({
 	}
 
 	> .notes {
-		> ::v-deep * {
+		> ::v-deep *:not(:last-child) {
 			margin-bottom: var(--marginFull);
 		}
 	}
 
 	&.max-width_500px {
 		> .notes {
-			> ::v-deep * {
+			> ::v-deep *:not(:last-child) {
 				margin-bottom: var(--marginHalf);
 			}
 		}
diff --git a/src/client/pages/note.vue b/src/client/pages/note.vue
index 3e4e21d346..73a0bb37ba 100644
--- a/src/client/pages/note.vue
+++ b/src/client/pages/note.vue
@@ -4,9 +4,19 @@
 	<portal to="title" v-if="note">{{ $t('noteOf', { user: note.user.name }) }}</portal>
 
 	<transition name="zoom" mode="out-in">
-		<x-note v-if="note" :note="note" :key="note.id" :detail="true"/>
-		<div v-else-if="error">
-			<mk-error @retry="fetch()"/>
+		<div v-if="note">
+			<mk-button v-if="hasNext && !showNext" @click="showNext = true" primary style="margin: 0 auto var(--margin) auto;"><fa :icon="faChevronUp"/></mk-button>
+			<x-notes v-if="showNext" ref="next" :pagination="next"/>
+			<hr v-if="showNext"/>
+
+			<x-note :note="note" :key="note.id" :detail="true"/>
+			<div v-if="error">
+				<mk-error @retry="fetch()"/>
+			</div>
+
+			<mk-button v-if="hasPrev && !showPrev" @click="showPrev = true" primary style="margin: var(--margin) auto 0 auto;"><fa :icon="faChevronDown"/></mk-button>
+			<hr v-if="showPrev"/>
+			<x-notes v-if="showPrev" ref="prev" :pagination="prev" style="margin-top: var(--margin);"/>
 		</div>
 	</transition>
 </div>
@@ -14,9 +24,12 @@
 
 <script lang="ts">
 import Vue from 'vue';
+import { faChevronUp, faChevronDown } from '@fortawesome/free-solid-svg-icons';
 import i18n from '../i18n';
 import Progress from '../scripts/loading';
 import XNote from '../components/note.vue';
+import XNotes from '../components/notes.vue';
+import MkButton from '../components/ui/button.vue';
 
 export default Vue.extend({
 	i18n,
@@ -26,12 +39,36 @@ export default Vue.extend({
 		};
 	},
 	components: {
-		XNote
+		XNote,
+		XNotes,
+		MkButton,
 	},
 	data() {
 		return {
 			note: null,
+			hasPrev: false,
+			hasNext: false,
+			showPrev: false,
+			showNext: false,
 			error: null,
+			prev: {
+				endpoint: 'users/notes',
+				limit: 10,
+				params: init => ({
+					userId: this.note.userId,
+					untilId: this.note.id,
+				})
+			},
+			next: {
+				reversed: true,
+				endpoint: 'users/notes',
+				limit: 10,
+				params: init => ({
+					userId: this.note.userId,
+					sinceId: this.note.id,
+				})
+			},
+			faChevronUp, faChevronDown
 		};
 	},
 	watch: {
@@ -46,7 +83,22 @@ export default Vue.extend({
 			this.$root.api('notes/show', {
 				noteId: this.$route.params.note
 			}).then(note => {
-				this.note = note;
+				Promise.all([
+					this.$root.api('users/notes', {
+						userId: note.userId,
+						untilId: note.id,
+						limit: 1,
+					}),
+					this.$root.api('users/notes', {
+						userId: note.userId,
+						sinceId: note.id,
+						limit: 1,
+					}),
+				]).then(([prev, next]) => {
+					this.hasPrev = prev.length !== 0;
+					this.hasNext = next.length !== 0;
+					this.note = note;
+				});
 			}).catch(e => {
 				this.error = e;
 			}).finally(() => {
diff --git a/src/client/scripts/paging.ts b/src/client/scripts/paging.ts
index 07eaf20ff3..64c744e45d 100644
--- a/src/client/scripts/paging.ts
+++ b/src/client/scripts/paging.ts
@@ -64,18 +64,18 @@ export default (opts) => ({
 			if (params && params.then) params = await params;
 			const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint;
 			await this.$root.api(endpoint, {
+				...params,
 				limit: this.pagination.noPaging ? (this.pagination.limit || 10) : (this.pagination.limit || 10) + 1,
-				...params
-			}).then(x => {
-				if (!this.pagination.noPaging && (x.length === (this.pagination.limit || 10) + 1)) {
-					x.pop();
-					this.items = x;
+			}).then(items => {
+				if (!this.pagination.noPaging && (items.length === (this.pagination.limit || 10) + 1)) {
+					items.pop();
+					this.items = this.pagination.reversed ? [...items].reverse() : items;
 					this.more = true;
 				} else {
-					this.items = x;
+					this.items = this.pagination.reversed ? [...items].reverse() : items;
 					this.more = false;
 				}
-				this.offset = x.length;
+				this.offset = items.length;
 				this.inited = true;
 				this.fetching = false;
 				if (opts.after) opts.after(this, null);
@@ -93,23 +93,25 @@ export default (opts) => ({
 			if (params && params.then) params = await params;
 			const endpoint = typeof this.pagination.endpoint === 'function' ? this.pagination.endpoint() : this.pagination.endpoint;
 			await this.$root.api(endpoint, {
+				...params,
 				limit: SECOND_FETCH_LIMIT + 1,
 				...(this.pagination.offsetMode ? {
 					offset: this.offset,
+				} : this.pagination.reversed ? {
+					sinceId: this.items[0].id,
 				} : {
 					untilId: this.items[this.items.length - 1].id,
 				}),
-				...params
-			}).then(x => {
-				if (x.length === SECOND_FETCH_LIMIT + 1) {
-					x.pop();
-					this.items = this.items.concat(x);
+			}).then(items => {
+				if (items.length === SECOND_FETCH_LIMIT + 1) {
+					items.pop();
+					this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items);
 					this.more = true;
 				} else {
-					this.items = this.items.concat(x);
+					this.items = this.pagination.reversed ? [...items].reverse().concat(this.items) : this.items.concat(items);
 					this.more = false;
 				}
-				this.offset += x.length;
+				this.offset += items.length;
 				this.moreFetching = false;
 			}, e => {
 				this.moreFetching = false;
diff --git a/src/client/style.scss b/src/client/style.scss
index b3891314c0..a9868a9491 100644
--- a/src/client/style.scss
+++ b/src/client/style.scss
@@ -128,6 +128,13 @@ a {
 	}
 }
 
+hr {
+	margin: var(--margin) 0 var(--margin) 0;
+	border: none;
+	height: 1px;
+	background: var(--divider);
+}
+
 #nprogress {
 	pointer-events: none;
 	position: absolute;