diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3e943714cc..33dfa28d02 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@
 ## next
 
 ### General
+- Enhance: タイムラインからRenoteを除外するオプションを追加
 - Enhance: ユーザーページのノート一覧でRenoteを除外できるように
 
 ### Client
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 5473a26fca..eb2793c710 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -1124,6 +1124,7 @@ export interface Locale {
     "authentication": string;
     "authenticationRequiredToContinue": string;
     "dateAndTime": string;
+    "showRenotes": string;
     "_announcement": {
         "forExistingUsers": string;
         "forExistingUsersDescription": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index ffe1d20e10..637d580d6a 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1121,6 +1121,7 @@ unnotifyNotes: "投稿の通知を解除"
 authentication: "認証"
 authenticationRequiredToContinue: "続けるには認証を行ってください"
 dateAndTime: "日時"
+showRenotes: "リノートを表示"
 
 _announcement:
   forExistingUsers: "既存ユーザーのみ"
diff --git a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
index 6932073791..c20274b2ba 100644
--- a/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
+++ b/packages/backend/src/server/api/endpoints/notes/user-list-timeline.ts
@@ -49,6 +49,8 @@ export const paramDef = {
 		includeMyRenotes: { type: 'boolean', default: true },
 		includeRenotedMyNotes: { type: 'boolean', default: true },
 		includeLocalRenotes: { type: 'boolean', default: true },
+		withReplies: { type: 'boolean', default: false },
+		withRenotes: { type: 'boolean', default: true },
 		withFiles: {
 			type: 'boolean',
 			default: false,
@@ -130,6 +132,20 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				}));
 			}
 
+			if (!ps.withReplies) {
+				query.andWhere('note.replyId IS NULL');
+			}
+
+			if (ps.withRenotes === false) {
+				query.andWhere(new Brackets(qb => {
+					qb.orWhere('note.renoteId IS NULL');
+					qb.orWhere(new Brackets(qb => {
+						qb.orWhere('note.text IS NOT NULL');
+						qb.orWhere('note.fileIds != \'{}\'');
+					}));
+				}));
+			}
+
 			if (ps.withFiles) {
 				query.andWhere('note.fileIds != \'{}\'');
 			}
diff --git a/packages/backend/src/server/api/endpoints/users/notes.ts b/packages/backend/src/server/api/endpoints/users/notes.ts
index 982fcc858a..e660a0bb25 100644
--- a/packages/backend/src/server/api/endpoints/users/notes.ts
+++ b/packages/backend/src/server/api/endpoints/users/notes.ts
@@ -41,8 +41,8 @@ export const paramDef = {
 	type: 'object',
 	properties: {
 		userId: { type: 'string', format: 'misskey:id' },
-		includeReplies: { type: 'boolean', default: true },
-		includeRenotes: { type: 'boolean', default: true },
+		withReplies: { type: 'boolean', default: false },
+		withRenotes: { type: 'boolean', default: true },
 		limit: { type: 'integer', minimum: 1, maximum: 100, default: 10 },
 		sinceId: { type: 'string', format: 'misskey:id' },
 		untilId: { type: 'string', format: 'misskey:id' },
@@ -115,11 +115,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				}
 			}
 
-			if (!ps.includeReplies) {
+			if (!ps.withReplies) {
 				query.andWhere('note.replyId IS NULL');
 			}
 
-			if (ps.includeRenotes === false) {
+			if (ps.withRenotes === false) {
 				query.andWhere(new Brackets(qb => {
 					qb.orWhere('note.renoteId IS NULL');
 					qb.orWhere(new Brackets(qb => {
diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts
index a33f1a956a..fef52b6856 100644
--- a/packages/backend/src/server/api/stream/channels/global-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts
@@ -19,6 +19,7 @@ class GlobalTimelineChannel extends Channel {
 	public static shouldShare = true;
 	public static requireCredential = false;
 	private withReplies: boolean;
+	private withRenotes: boolean;
 
 	constructor(
 		private metaService: MetaService,
@@ -37,7 +38,8 @@ class GlobalTimelineChannel extends Channel {
 		const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null);
 		if (!policies.gtlAvailable) return;
 
-		this.withReplies = params.withReplies as boolean;
+		this.withReplies = params.withReplies ?? false;
+		this.withRenotes = params.withRenotes ?? true;
 
 		// Subscribe events
 		this.subscriber.on('notesStream', this.onNote);
@@ -68,6 +70,8 @@ class GlobalTimelineChannel extends Channel {
 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
 		}
 
+		if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return;
+
 		// Ignore notes from instances the user has muted
 		if (isInstanceMuted(note, new Set<string>(this.userProfile?.mutedInstances ?? []))) return;
 
diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts
index bd8888f679..198c68e1c2 100644
--- a/packages/backend/src/server/api/stream/channels/home-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts
@@ -17,6 +17,7 @@ class HomeTimelineChannel extends Channel {
 	public static shouldShare = true;
 	public static requireCredential = true;
 	private withReplies: boolean;
+	private withRenotes: boolean;
 
 	constructor(
 		private noteEntityService: NoteEntityService,
@@ -30,7 +31,8 @@ class HomeTimelineChannel extends Channel {
 
 	@bindThis
 	public async init(params: any) {
-		this.withReplies = params.withReplies as boolean;
+		this.withReplies = params.withReplies ?? false;
+		this.withRenotes = params.withRenotes ?? true;
 
 		this.subscriber.on('notesStream', this.onNote);
 	}
@@ -77,6 +79,8 @@ class HomeTimelineChannel extends Channel {
 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
 		}
 
+		if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return;
+
 		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
 		if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
index 760fb8d19f..cde4297478 100644
--- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts
@@ -19,6 +19,7 @@ class HybridTimelineChannel extends Channel {
 	public static shouldShare = true;
 	public static requireCredential = true;
 	private withReplies: boolean;
+	private withRenotes: boolean;
 
 	constructor(
 		private metaService: MetaService,
@@ -37,7 +38,8 @@ class HybridTimelineChannel extends Channel {
 		const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null);
 		if (!policies.ltlAvailable) return;
 
-		this.withReplies = params.withReplies as boolean;
+		this.withReplies = params.withReplies ?? false;
+		this.withRenotes = params.withRenotes ?? true;
 
 		// Subscribe events
 		this.subscriber.on('notesStream', this.onNote);
@@ -89,6 +91,8 @@ class HybridTimelineChannel extends Channel {
 			if (reply.userId !== this.user!.id && note.userId !== this.user!.id && reply.userId !== note.userId) return;
 		}
 
+		if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return;
+
 		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
 		if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts
index f32f8c5cec..ef708c4fee 100644
--- a/packages/backend/src/server/api/stream/channels/local-timeline.ts
+++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts
@@ -18,6 +18,7 @@ class LocalTimelineChannel extends Channel {
 	public static shouldShare = true;
 	public static requireCredential = false;
 	private withReplies: boolean;
+	private withRenotes: boolean;
 
 	constructor(
 		private metaService: MetaService,
@@ -36,7 +37,8 @@ class LocalTimelineChannel extends Channel {
 		const policies = await this.roleService.getUserPolicies(this.user ? this.user.id : null);
 		if (!policies.ltlAvailable) return;
 
-		this.withReplies = params.withReplies as boolean;
+		this.withReplies = params.withReplies ?? false;
+		this.withRenotes = params.withRenotes ?? true;
 
 		// Subscribe events
 		this.subscriber.on('notesStream', this.onNote);
@@ -68,6 +70,8 @@ class LocalTimelineChannel extends Channel {
 			if (reply.userId !== this.user.id && note.userId !== this.user.id && reply.userId !== note.userId) return;
 		}
 
+		if (note.renote && note.text == null && (note.fileIds == null || note.fileIds.length === 0) && !this.withRenotes) return;
+
 		// 流れてきたNoteがミュートしているユーザーが関わるものだったら無視する
 		if (isUserRelated(note, this.userIdsWhoMeMuting)) return;
 		// 流れてきたNoteがブロックされているユーザーが関わるものだったら無視する
diff --git a/packages/frontend/src/components/MkTimeline.vue b/packages/frontend/src/components/MkTimeline.vue
index d6712e7606..3e7c537512 100644
--- a/packages/frontend/src/components/MkTimeline.vue
+++ b/packages/frontend/src/components/MkTimeline.vue
@@ -15,14 +15,19 @@ import * as sound from '@/scripts/sound.js';
 import { $i } from '@/account.js';
 import { defaultStore } from '@/store.js';
 
-const props = defineProps<{
+const props = withDefaults(defineProps<{
 	src: string;
 	list?: string;
 	antenna?: string;
 	channel?: string;
 	role?: string;
 	sound?: boolean;
-}>();
+	withRenotes?: boolean;
+	withReplies?: boolean;
+}>(), {
+	withRenotes: true,
+	withReplies: false,
+});
 
 const emit = defineEmits<{
 	(ev: 'note'): void;
@@ -62,10 +67,12 @@ if (props.src === 'antenna') {
 } else if (props.src === 'home') {
 	endpoint = 'notes/timeline';
 	query = {
-		withReplies: defaultStore.state.showTimelineReplies,
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 	};
 	connection = stream.useChannel('homeTimeline', {
-		withReplies: defaultStore.state.showTimelineReplies,
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 	});
 	connection.on('note', prepend);
 
@@ -73,28 +80,34 @@ if (props.src === 'antenna') {
 } else if (props.src === 'local') {
 	endpoint = 'notes/local-timeline';
 	query = {
-		withReplies: defaultStore.state.showTimelineReplies,
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 	};
 	connection = stream.useChannel('localTimeline', {
-		withReplies: defaultStore.state.showTimelineReplies,
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 	});
 	connection.on('note', prepend);
 } else if (props.src === 'social') {
 	endpoint = 'notes/hybrid-timeline';
 	query = {
-		withReplies: defaultStore.state.showTimelineReplies,
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 	};
 	connection = stream.useChannel('hybridTimeline', {
-		withReplies: defaultStore.state.showTimelineReplies,
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 	});
 	connection.on('note', prepend);
 } else if (props.src === 'global') {
 	endpoint = 'notes/global-timeline';
 	query = {
-		withReplies: defaultStore.state.showTimelineReplies,
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 	};
 	connection = stream.useChannel('globalTimeline', {
-		withReplies: defaultStore.state.showTimelineReplies,
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 	});
 	connection.on('note', prepend);
 } else if (props.src === 'mentions') {
@@ -116,9 +129,13 @@ if (props.src === 'antenna') {
 } else if (props.src === 'list') {
 	endpoint = 'notes/user-list-timeline';
 	query = {
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 		listId: props.list,
 	};
 	connection = stream.useChannel('userList', {
+		withRenotes: props.withRenotes,
+		withReplies: props.withReplies,
 		listId: props.list,
 	});
 	connection.on('note', prepend);
diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue
index 217cd6ccf4..771f43c66b 100644
--- a/packages/frontend/src/pages/settings/general.vue
+++ b/packages/frontend/src/pages/settings/general.vue
@@ -29,7 +29,6 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<div class="_gaps_s">
 			<MkSwitch v-model="showFixedPostForm">{{ i18n.ts.showFixedPostForm }}</MkSwitch>
 			<MkSwitch v-model="showFixedPostFormInChannel">{{ i18n.ts.showFixedPostFormInChannel }}</MkSwitch>
-			<MkSwitch v-model="showTimelineReplies">{{ i18n.ts.flagShowTimelineReplies }}<template #caption>{{ i18n.ts.flagShowTimelineRepliesDescription }} {{ i18n.ts.reflectMayTakeTime }}</template></MkSwitch>
 			<MkFolder>
 				<template #label>{{ i18n.ts.pinnedList }}</template>
 				<!-- 複数ピン止め管理できるようにしたいけどめんどいので一旦ひとつのみ -->
@@ -253,7 +252,6 @@ const squareAvatars = computed(defaultStore.makeGetterSetter('squareAvatars'));
 const mediaListWithOneImageAppearance = computed(defaultStore.makeGetterSetter('mediaListWithOneImageAppearance'));
 const notificationPosition = computed(defaultStore.makeGetterSetter('notificationPosition'));
 const notificationStackAxis = computed(defaultStore.makeGetterSetter('notificationStackAxis'));
-const showTimelineReplies = computed(defaultStore.makeGetterSetter('showTimelineReplies'));
 const keepScreenOn = computed(defaultStore.makeGetterSetter('keepScreenOn'));
 
 watch(lang, () => {
diff --git a/packages/frontend/src/pages/timeline.vue b/packages/frontend/src/pages/timeline.vue
index cce7360b9b..5fc43dc650 100644
--- a/packages/frontend/src/pages/timeline.vue
+++ b/packages/frontend/src/pages/timeline.vue
@@ -15,9 +15,11 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div :class="$style.tl">
 				<MkTimeline
 					ref="tlComponent"
-					:key="src"
+					:key="src + withRenotes + withReplies"
 					:src="src.split(':')[0]"
 					:list="src.split(':')[1]"
+					:withRenotes="withRenotes"
+					:withReplies="withReplies"
 					:sound="true"
 					@queue="queueUpdated"
 				/>
@@ -58,6 +60,8 @@ const rootEl = $shallowRef<HTMLElement>();
 let queue = $ref(0);
 let srcWhenNotSignin = $ref(isLocalTimelineAvailable ? 'local' : 'global');
 const src = $computed({ get: () => ($i ? defaultStore.reactiveState.tl.value.src : srcWhenNotSignin), set: (x) => saveSrc(x) });
+const withRenotes = $ref(true);
+const withReplies = $ref(false);
 
 watch($$(src), () => queue = 0);
 
@@ -129,7 +133,23 @@ function focus(): void {
 	tlComponent.focus();
 }
 
-const headerActions = $computed(() => []);
+const headerActions = $computed(() => [{
+	icon: 'ti ti-dots',
+	text: i18n.ts.options,
+	handler: (ev) => {
+		os.popupMenu([{
+			type: 'switch',
+			text: i18n.ts.showRenotes,
+			icon: 'ti ti-repeat',
+			ref: $$(withRenotes),
+		}, {
+			type: 'switch',
+			text: i18n.ts.withReplies,
+			icon: 'ti ti-arrow-back-up',
+			ref: $$(withReplies),
+		}], ev.currentTarget ?? ev.target);
+	},
+}]);
 
 const headerTabs = $computed(() => [...(defaultStore.reactiveState.pinnedUserLists.value.map(l => ({
 	key: 'list:' + l.id,
diff --git a/packages/frontend/src/pages/user/index.timeline.vue b/packages/frontend/src/pages/user/index.timeline.vue
index fcb2b41651..42040f5304 100644
--- a/packages/frontend/src/pages/user/index.timeline.vue
+++ b/packages/frontend/src/pages/user/index.timeline.vue
@@ -36,8 +36,8 @@ const pagination = {
 	limit: 10,
 	params: computed(() => ({
 		userId: props.user.id,
-		includeRenotes: include.value === 'all',
-		includeReplies: include.value === 'all' || include.value === 'files',
+		withRenotes: include.value === 'all',
+		withReplies: include.value === 'all' || include.value === 'files',
 		withFiles: include.value === 'files',
 	})),
 };