diff --git a/components/account/AccountTabs.vue b/components/account/AccountTabs.vue
new file mode 100644
index 00000000..ba3e3f5f
--- /dev/null
+++ b/components/account/AccountTabs.vue
@@ -0,0 +1,41 @@
+<script setup lang="ts">
+const { t } = useI18n()
+const route = useRoute()
+
+const server = $(computedEager(() => route.params.server as string))
+const account = $(computedEager(() => route.params.account as string))
+
+const tabs = $computed(() => [
+  {
+    name: 'account-index',
+    to: {
+      name: 'account-index',
+      params: { server, account },
+    },
+    display: t('tab.posts'),
+    icon: 'i-ri:file-list-2-line',
+  },
+  {
+    name: 'account-replies',
+    to: {
+      name: 'account-replies',
+      params: { server, account },
+    },
+    display: t('tab.posts_with_replies'),
+    icon: 'i-ri:chat-3-line',
+  },
+  {
+    name: 'account-media',
+    to: {
+      name: 'account-media',
+      params: { server, account },
+    },
+    display: t('tab.media'),
+    icon: 'i-ri:camera-2-line',
+  },
+] as const)
+</script>
+
+<template>
+  <CommonRouteTabs force :options="tabs" prevent-scroll-top command />
+</template>
diff --git a/components/common/CommonRouteTabs.vue b/components/common/CommonRouteTabs.vue
index 643568e2..65d8864b 100644
--- a/components/common/CommonRouteTabs.vue
+++ b/components/common/CommonRouteTabs.vue
@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import type { RouteLocationRaw } from 'vue-router'
 
-const { options, command, replace } = $defineProps<{
+const { options, command, replace, preventScrollTop = false } = $defineProps<{
   options: {
     to: RouteLocationRaw
     display: string
@@ -10,6 +10,7 @@ const { options, command, replace } = $defineProps<{
   }[]
   command?: boolean
   replace?: boolean
+  preventScrollTop?: boolean
 }>()
 
 const router = useRouter()
@@ -36,7 +37,7 @@ useCommands(() => command
       tabindex="1"
       hover:bg-active transition-100
       exact-active-class="children:(font-bold !border-primary !op100)"
-      @click="$scrollToTop"
+      @click="!preventScrollTop && $scrollToTop()"
     >
       <span ws-nowrap mxa sm:px2 sm:py3 py2 text-center border-b-3 op50 hover:op70 border-transparent>{{ option.display }}</span>
     </NuxtLink>
diff --git a/locales/en-US.json b/locales/en-US.json
index 2ea059c2..662cfa92 100644
--- a/locales/en-US.json
+++ b/locales/en-US.json
@@ -8,6 +8,7 @@
     "follow": "Follow",
     "follow_back": "Follow back",
     "follow_requested": "Requested",
+    "followers": "Followers",
     "followers_count": "{0} Followers",
     "following": "Following",
     "following_count": "{0} Following",
@@ -18,6 +19,7 @@
     "muted_users": "Muted users",
     "mutuals": "Mutuals",
     "pinned": "Pinned",
+    "posts": "Posts",
     "posts_count": "{0} Posts",
     "profile_description": "{0}'s profile header",
     "profile_unavailable": "Profile unavailable",
diff --git a/locales/es-ES.json b/locales/es-ES.json
index 8e67dc6c..ef2fe170 100644
--- a/locales/es-ES.json
+++ b/locales/es-ES.json
@@ -8,6 +8,7 @@
     "follow": "Seguir",
     "follow_back": "Seguir de vuelta",
     "follow_requested": "Enviado",
+    "followers": "Seguidores",
     "followers_count": "{0} Seguidores|{0} Seguidor|{0} Seguidores",
     "following": "Siguiendo",
     "following_count": "{0} Siguiendo",
@@ -18,6 +19,7 @@
     "muted_users": "Usuarios silenciados",
     "mutuals": "Mutuo",
     "pinned": "Publicaciones fijadas",
+    "posts": "Publicaciones",
     "posts_count": "{0} publicaciones|{0} publicación|{0} publicaciones",
     "profile_description": "Encabezado del perfil de {0}",
     "profile_unavailable": "Perfil no disponible",
@@ -172,7 +174,7 @@
   "tab": {
     "for_you": "Para tí",
     "hashtags": "Etiquetas",
-    "media": "Medios de comunicación",
+    "media": "Multimedia",
     "news": "Noticias",
     "notifications_all": "Todas",
     "notifications_mention": "Menciones",
diff --git a/pages/[[server]]/@[account]/index.vue b/pages/[[server]]/@[account]/index.vue
index a6bbb4d5..59bda25c 100644
--- a/pages/[[server]]/@[account]/index.vue
+++ b/pages/[[server]]/@[account]/index.vue
@@ -11,12 +11,6 @@ const { t } = useI18n()
 const { data: account, refresh } = $(await useAsyncData(() => fetchAccountByHandle(accountName).catch(() => null)))
 const relationship = $computed(() => account ? useRelationship(account).value : undefined)
 
-if (account) {
-  useHeadFixed({
-    title: () => `${getDisplayName(account)} (@${account.acct})`,
-  })
-}
-
 onReactivated(() => {
   // Silently update data when reentering the page
   // The user will see the previous content first, and any changes will be updated to the UI when the request is completed
diff --git a/pages/[[server]]/@[account]/index/followers.vue b/pages/[[server]]/@[account]/index/followers.vue
index 0a749e59..3369f252 100644
--- a/pages/[[server]]/@[account]/index/followers.vue
+++ b/pages/[[server]]/@[account]/index/followers.vue
@@ -1,4 +1,5 @@
 <script setup lang="ts">
+const { t } = useI18n()
 const params = useRoute().params
 const handle = $(computedEager(() => params.account as string))
 
@@ -6,6 +7,12 @@ definePageMeta({ name: 'account-followers' })
 
 const account = await fetchAccountByHandle(handle)
 const paginator = account ? useMasto().accounts.iterateFollowers(account.id, {}) : null
+
+if (account) {
+  useHeadFixed({
+    title: () => `${t('account.followers')} | ${getDisplayName(account)} (@${account})`,
+  })
+}
 </script>
 
 <template>
diff --git a/pages/[[server]]/@[account]/index/following.vue b/pages/[[server]]/@[account]/index/following.vue
index 62e2011b..80e2b8c1 100644
--- a/pages/[[server]]/@[account]/index/following.vue
+++ b/pages/[[server]]/@[account]/index/following.vue
@@ -1,4 +1,5 @@
 <script setup lang="ts">
+const { t } = useI18n()
 const params = useRoute().params
 const handle = $(computedEager(() => params.account as string))
 
@@ -6,6 +7,12 @@ definePageMeta({ name: 'account-following' })
 
 const account = await fetchAccountByHandle(handle)
 const paginator = account ? useMasto().accounts.iterateFollowing(account.id, {}) : null
+
+if (account) {
+  useHeadFixed({
+    title: () => `${t('account.following')} | ${getDisplayName(account)} (@${account})`,
+  })
+}
 </script>
 
 <template>
diff --git a/pages/[[server]]/@[account]/index/index.vue b/pages/[[server]]/@[account]/index/index.vue
index 1187d420..b11a3bfd 100644
--- a/pages/[[server]]/@[account]/index/index.vue
+++ b/pages/[[server]]/@[account]/index/index.vue
@@ -1,52 +1,31 @@
 <script setup lang="ts">
 import type { Account } from 'masto'
+import AccountTabs from '~/components/account/AccountTabs.vue'
 
 const params = useRoute().params
 const handle = $(computedEager(() => params.account as string))
 
 definePageMeta({ name: 'account-index' })
 
-const { data: account } = await useAsyncData(`account:${handle}`, async () => (
-  window.history.state?.account as Account | undefined)
-  ?? await fetchAccountByHandle(handle),
-)
 const { t } = useI18n()
 
-const paginatorPosts = useMasto().accounts.iterateStatuses(account.value!.id, { excludeReplies: true })
-const paginatorPostsWithReply = useMasto().accounts.iterateStatuses(account.value!.id, { excludeReplies: false })
-const paginatorMedia = useMasto().accounts.iterateStatuses(account.value!.id, { onlyMedia: true, excludeReplies: false })
+const { data: account } = await useAsyncData(`account:${handle}`, async () => (
+  window.history.state?.account as Account | undefined)
+    ?? await fetchAccountByHandle(handle),
+)
 
-const tabs = $computed(() => [
-  {
-    name: 'posts',
-    display: t('tab.posts'),
-    icon: 'i-ri:file-list-2-line',
-    paginator: paginatorPosts,
-  },
-  {
-    name: 'relies',
-    display: t('tab.posts_with_replies'),
-    icon: 'i-ri:chat-3-line',
-    paginator: paginatorPostsWithReply,
-  },
-  {
-    name: 'media',
-    display: t('tab.media'),
-    icon: 'i-ri:camera-2-line',
-    paginator: paginatorMedia,
-  },
-] as const)
+const paginator = useMasto().accounts.iterateStatuses(account.value!.id, { excludeReplies: true })
 
-// Don't use local storage because it is better to default to Posts every time you visit a user's profile.
-const tab = $ref(tabs[0].name)
-const paginator = $computed(() => tabs.find(t => t.name === tab)!.paginator)
+if (account) {
+  useHeadFixed({
+    title: () => `${t('account.posts')} | ${getDisplayName(account.value!)} (@${account.value!.acct})`,
+  })
+}
 </script>
 
 <template>
   <div>
-    <CommonTabs v-model="tab" :options="tabs" command />
-    <KeepAlive>
-      <TimelinePaginator :key="tab" :paginator="paginator" context="account" />
-    </KeepAlive>
+    <AccountTabs />
+    <TimelinePaginator :paginator="paginator" context="account" />
   </div>
 </template>
diff --git a/pages/[[server]]/@[account]/index/media.vue b/pages/[[server]]/@[account]/index/media.vue
new file mode 100644
index 00000000..385ba498
--- /dev/null
+++ b/pages/[[server]]/@[account]/index/media.vue
@@ -0,0 +1,29 @@
+<script setup lang="ts">
+import type { Account } from 'masto'
+
+definePageMeta({ name: 'account-media' })
+
+const { t } = useI18n()
+const params = useRoute().params
+const handle = $(computedEager(() => params.account as string))
+
+const { data: account } = await useAsyncData(`account:${handle}`, async () => (
+  window.history.state?.account as Account | undefined)
+    ?? await fetchAccountByHandle(handle),
+)
+
+const paginator = useMasto().accounts.iterateStatuses(account.value!.id, { onlyMedia: true, excludeReplies: false })
+
+if (account) {
+  useHeadFixed({
+    title: () => `${t('tab.media')} | ${getDisplayName(account.value!)} (@${account.value!.acct})`,
+  })
+}
+</script>
+
+<template>
+  <div>
+    <AccountTabs />
+    <TimelinePaginator :paginator="paginator" context="account" />
+  </div>
+</template>
diff --git a/pages/[[server]]/@[account]/index/with_replies.vue b/pages/[[server]]/@[account]/index/with_replies.vue
new file mode 100644
index 00000000..a3af2523
--- /dev/null
+++ b/pages/[[server]]/@[account]/index/with_replies.vue
@@ -0,0 +1,29 @@
+<script setup lang="ts">
+import type { Account } from 'masto'
+
+definePageMeta({ name: 'account-replies' })
+
+const { t } = useI18n()
+const params = useRoute().params
+const handle = $(computedEager(() => params.account as string))
+
+const { data: account } = await useAsyncData(`account:${handle}`, async () => (
+  window.history.state?.account as Account | undefined)
+    ?? await fetchAccountByHandle(handle),
+)
+
+const paginator = useMasto().accounts.iterateStatuses(account.value!.id, { excludeReplies: false })
+
+if (account) {
+  useHeadFixed({
+    title: () => `${t('tab.posts_with_replies')} | ${getDisplayName(account.value!)} (@${account.value!.acct})`,
+  })
+}
+</script>
+
+<template>
+  <div>
+    <AccountTabs />
+    <TimelinePaginator :paginator="paginator" context="account" />
+  </div>
+</template>