diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue
index b22cd683ff..163cba5e3c 100644
--- a/packages/frontend/src/components/MkPageWindow.vue
+++ b/packages/frontend/src/components/MkPageWindow.vue
@@ -99,6 +99,7 @@ provideMetadataReceiver((info) => {
 provide('shouldOmitHeaderTitle', true);
 provide('shouldHeaderThin', true);
 provide('forceSpacerMin', true);
+provide('shouldBackButton', false);
 
 const contextmenu = $computed(() => ([{
 	icon: 'ph-eject ph-bold ph-lg',
diff --git a/packages/frontend/src/components/global/MkPageHeader.vue b/packages/frontend/src/components/global/MkPageHeader.vue
index 2134e9fad3..56fe920252 100644
--- a/packages/frontend/src/components/global/MkPageHeader.vue
+++ b/packages/frontend/src/components/global/MkPageHeader.vue
@@ -9,9 +9,18 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div v-if="!thin_ && narrow && props.displayMyAvatar && $i" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
 			<MkAvatar :class="$style.avatar" :user="$i"/>
 		</div>
-		<div v-else-if="!thin_ && narrow && !hideTitle" :class="$style.buttonsLeft"/>
+		<div v-else-if="!thin_ && narrow && !hideTitle" :class="$style.buttonsLeft">
+			<button v-if="displayBackButton" class="_button" :class="$style.button" @click.stop="goBack()" @touchstart="preventDrag">
+				<i class="ph-caret-left ph-bold ph-lg"></i>
+			</button>
+		</div>
 
 		<template v-if="metadata">
+			<div v-if="displayBackButton && !narrow" :class="$style.buttonsLeft">
+				<button class="_button" :class="$style.button" @click.stop="goBack()" @touchstart="preventDrag">
+					<i class="ph-caret-left ph-bold ph-lg"></i>
+				</button>
+			</div>
 			<div v-if="!hideTitle" :class="$style.titleContainer" @click="top">
 				<div v-if="metadata.avatar" :class="$style.titleAvatarContainer">
 					<MkAvatar :class="$style.titleAvatar" :user="metadata.avatar" indicator/>
@@ -48,6 +57,7 @@ import { scrollToTop } from '@/scripts/scroll.js';
 import { globalEvents } from '@/events.js';
 import { injectPageMetadata } from '@/scripts/page-metadata.js';
 import { $i, openAccountMenu as openAccountMenu_ } from '@/account.js';
+import { instance } from '@/instance.js';
 
 const props = withDefaults(defineProps<{
 	tabs?: Tab[];
@@ -60,6 +70,7 @@ const props = withDefaults(defineProps<{
 	}[];
 	thin?: boolean;
 	displayMyAvatar?: boolean;
+	displayBackButton?: boolean;
 }>(), {
 	tabs: () => ([] as Tab[]),
 });
@@ -68,6 +79,8 @@ const emit = defineEmits<{
 	(ev: 'update:tab', key: string);
 }>();
 
+const displayBackButton = props.displayBackButton && history.state.key !== 'index' && history.length > 1 && inject('shouldBackButton', true);
+
 const metadata = injectPageMetadata();
 
 const hideTitle = inject('shouldOmitHeaderTitle', false);
@@ -102,6 +115,10 @@ function onTabClick(): void {
 	top();
 }
 
+function goBack(): void {
+	window.history.back();
+}
+
 const calcBg = () => {
 	const rawBg = 'var(--bg)';
 	const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
diff --git a/packages/frontend/src/pages/note.vue b/packages/frontend/src/pages/note.vue
index 9bafa17005..14f9ff3816 100644
--- a/packages/frontend/src/pages/note.vue
+++ b/packages/frontend/src/pages/note.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkStickyContainer>
-	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
+	<template #header><MkPageHeader :actions="headerActions" :displayBackButton="true" :tabs="headerTabs"/></template>
 	<MkSpacer :contentMax="800">
 		<div>
 			<Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
diff --git a/packages/frontend/src/pages/page.vue b/packages/frontend/src/pages/page.vue
index 1bb65d0cef..962d910405 100644
--- a/packages/frontend/src/pages/page.vue
+++ b/packages/frontend/src/pages/page.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkStickyContainer>
-	<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
+	<template #header><MkPageHeader :actions="headerActions" :displayBackButton="true" :tabs="headerTabs"/></template>
 	<MkSpacer :contentMax="700">
 		<Transition :name="defaultStore.state.animation ? 'fade' : ''" mode="out-in">
 			<div v-if="page" :key="page.id" class="xcukqgmh">
diff --git a/packages/frontend/src/pages/user/index.vue b/packages/frontend/src/pages/user/index.vue
index dd64cc2534..df07dd9786 100644
--- a/packages/frontend/src/pages/user/index.vue
+++ b/packages/frontend/src/pages/user/index.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <MkStickyContainer>
-	<template #header><MkPageHeader v-model:tab="tab" :actions="headerActions" :tabs="headerTabs"/></template>
+	<template #header><MkPageHeader v-model:tab="tab" :displayBackButton="true" :actions="headerActions" :tabs="headerTabs"/></template>
 	<div>
 		<div v-if="user">
 			<XHome v-if="tab === 'home'" :user="user"/>