diff --git a/CHANGELOG.md b/CHANGELOG.md
index 269f8b1000..43cf0ef6e9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,8 @@ You should also include the user name that made the change.
 - Firefox109以下はサポートされなくなりました
 
 #### For app developers
+- API: metaのレスポンスに`emojis`プロパティが含まれなくなりました
+	- カスタム絵文字一覧情報を取得するには、`emojis`エンドポイントにリクエストします
 - API: カスタム絵文字エンティティに`url`プロパティが含まれなくなりました
 	- 絵文字画像を表示するには、`<instance host>/emoji/<emoji name>.webp`にリクエストすると画像が返ります。
 	- e.g. `https://p1.a9z.dev/emoji/misskey.webp`
diff --git a/packages/backend/src/core/entities/EmojiEntityService.ts b/packages/backend/src/core/entities/EmojiEntityService.ts
index 8a2dc70eda..2a4e09519f 100644
--- a/packages/backend/src/core/entities/EmojiEntityService.ts
+++ b/packages/backend/src/core/entities/EmojiEntityService.ts
@@ -22,23 +22,25 @@ export class EmojiEntityService {
 	@bindThis
 	public async pack(
 		src: Emoji['id'] | Emoji,
+		opts: { omitHost?: boolean; omitId?: boolean; } = {},
 	): Promise<Packed<'Emoji'>> {
 		const emoji = typeof src === 'object' ? src : await this.emojisRepository.findOneByOrFail({ id: src });
 
 		return {
-			id: emoji.id,
+			id: opts.omitId ? undefined : emoji.id,
 			aliases: emoji.aliases,
 			name: emoji.name,
 			category: emoji.category,
-			host: emoji.host,
+			host: opts.omitHost ? undefined : emoji.host,
 		};
 	}
 
 	@bindThis
 	public packMany(
 		emojis: any[],
+		opts: { omitHost?: boolean; omitId?: boolean; } = {},
 	) {
-		return Promise.all(emojis.map(x => this.pack(x)));
+		return Promise.all(emojis.map(x => this.pack(x, opts)));
 	}
 }
 
diff --git a/packages/backend/src/models/schema/emoji.ts b/packages/backend/src/models/schema/emoji.ts
index 9a52609b68..d897a0fc05 100644
--- a/packages/backend/src/models/schema/emoji.ts
+++ b/packages/backend/src/models/schema/emoji.ts
@@ -3,7 +3,7 @@ export const packedEmojiSchema = {
 	properties: {
 		id: {
 			type: 'string',
-			optional: false, nullable: false,
+			optional: true, nullable: false,
 			format: 'id',
 			example: 'xxxxxxxxxx',
 		},
@@ -26,12 +26,8 @@ export const packedEmojiSchema = {
 		},
 		host: {
 			type: 'string',
-			optional: false, nullable: true,
+			optional: true, nullable: true,
 			description: 'The local host is represented with `null`.',
 		},
-		url: {
-			type: 'string',
-			optional: true, nullable: false,
-		},
 	},
 } as const;
diff --git a/packages/backend/src/server/api/EndpointsModule.ts b/packages/backend/src/server/api/EndpointsModule.ts
index 60beca4f47..ab9349966d 100644
--- a/packages/backend/src/server/api/EndpointsModule.ts
+++ b/packages/backend/src/server/api/EndpointsModule.ts
@@ -220,6 +220,7 @@ import * as ep___messaging_messages_create from './endpoints/messaging/messages/
 import * as ep___messaging_messages_delete from './endpoints/messaging/messages/delete.js';
 import * as ep___messaging_messages_read from './endpoints/messaging/messages/read.js';
 import * as ep___meta from './endpoints/meta.js';
+import * as ep___emojis from './endpoints/emojis.js';
 import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js';
 import * as ep___mute_create from './endpoints/mute/create.js';
 import * as ep___mute_delete from './endpoints/mute/delete.js';
@@ -550,6 +551,7 @@ const $messaging_messages_create: Provider = { provide: 'ep:messaging/messages/c
 const $messaging_messages_delete: Provider = { provide: 'ep:messaging/messages/delete', useClass: ep___messaging_messages_delete.default };
 const $messaging_messages_read: Provider = { provide: 'ep:messaging/messages/read', useClass: ep___messaging_messages_read.default };
 const $meta: Provider = { provide: 'ep:meta', useClass: ep___meta.default };
+const $emojis: Provider = { provide: 'ep:emojis', useClass: ep___emojis.default };
 const $miauth_genToken: Provider = { provide: 'ep:miauth/gen-token', useClass: ep___miauth_genToken.default };
 const $mute_create: Provider = { provide: 'ep:mute/create', useClass: ep___mute_create.default };
 const $mute_delete: Provider = { provide: 'ep:mute/delete', useClass: ep___mute_delete.default };
@@ -884,6 +886,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
 		$messaging_messages_delete,
 		$messaging_messages_read,
 		$meta,
+		$emojis,
 		$miauth_genToken,
 		$mute_create,
 		$mute_delete,
@@ -1212,6 +1215,7 @@ const $retention: Provider = { provide: 'ep:retention', useClass: ep___retention
 		$messaging_messages_delete,
 		$messaging_messages_read,
 		$meta,
+		$emojis,
 		$miauth_genToken,
 		$mute_create,
 		$mute_delete,
diff --git a/packages/backend/src/server/api/endpoints.ts b/packages/backend/src/server/api/endpoints.ts
index d4f8be5b85..f9749ad660 100644
--- a/packages/backend/src/server/api/endpoints.ts
+++ b/packages/backend/src/server/api/endpoints.ts
@@ -219,6 +219,7 @@ import * as ep___messaging_messages_create from './endpoints/messaging/messages/
 import * as ep___messaging_messages_delete from './endpoints/messaging/messages/delete.js';
 import * as ep___messaging_messages_read from './endpoints/messaging/messages/read.js';
 import * as ep___meta from './endpoints/meta.js';
+import * as ep___emojis from './endpoints/emojis.js';
 import * as ep___miauth_genToken from './endpoints/miauth/gen-token.js';
 import * as ep___mute_create from './endpoints/mute/create.js';
 import * as ep___mute_delete from './endpoints/mute/delete.js';
@@ -547,6 +548,7 @@ const eps = [
 	['messaging/messages/delete', ep___messaging_messages_delete],
 	['messaging/messages/read', ep___messaging_messages_read],
 	['meta', ep___meta],
+	['emojis', ep___emojis],
 	['miauth/gen-token', ep___miauth_genToken],
 	['mute/create', ep___mute_create],
 	['mute/delete', ep___mute_delete],
diff --git a/packages/backend/src/server/api/endpoints/emojis.ts b/packages/backend/src/server/api/endpoints/emojis.ts
new file mode 100644
index 0000000000..0a16268229
--- /dev/null
+++ b/packages/backend/src/server/api/endpoints/emojis.ts
@@ -0,0 +1,91 @@
+import { IsNull, MoreThan } from 'typeorm';
+import { Inject, Injectable } from '@nestjs/common';
+import type { EmojisRepository } from '@/models/index.js';
+import { Endpoint } from '@/server/api/endpoint-base.js';
+import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
+import type { Config } from '@/config.js';
+import { DI } from '@/di-symbols.js';
+
+export const meta = {
+	tags: ['meta'],
+
+	requireCredential: false,
+
+	res: {
+		type: 'object',
+		optional: false, nullable: false,
+		properties: {
+			emojis: {
+				type: 'array',
+				optional: false, nullable: false,
+				items: {
+					type: 'object',
+					optional: false, nullable: false,
+					properties: {
+						id: {
+							type: 'string',
+							optional: false, nullable: false,
+							format: 'id',
+						},
+						aliases: {
+							type: 'array',
+							optional: false, nullable: false,
+							items: {
+								type: 'string',
+								optional: false, nullable: false,
+							},
+						},
+						category: {
+							type: 'string',
+							optional: false, nullable: true,
+						},
+					},
+				},
+			},
+		},
+	},
+} as const;
+
+export const paramDef = {
+	type: 'object',
+	properties: {
+	},
+	required: [],
+} as const;
+
+// eslint-disable-next-line import/no-default-export
+@Injectable()
+export default class extends Endpoint<typeof meta, typeof paramDef> {
+	constructor(
+		@Inject(DI.config)
+		private config: Config,
+	
+		@Inject(DI.emojisRepository)
+		private emojisRepository: EmojisRepository,
+
+		private emojiEntityService: EmojiEntityService,
+	) {
+		super(meta, paramDef, async (ps, me) => {
+			const emojis = await this.emojisRepository.find({
+				where: {
+					host: IsNull(),
+				},
+				order: {
+					category: 'ASC',
+					name: 'ASC',
+				},
+				cache: {
+					id: 'meta_emojis',
+					milliseconds: 3600000,	// 1 hour
+				},
+			});
+
+			return {
+				emojis: await this.emojiEntityService.packMany(emojis, {
+					omitId: true,
+					omitHost: true,
+				}),
+			};
+		});
+	}
+}
diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts
index 05da011979..c44d63d64b 100644
--- a/packages/backend/src/server/api/endpoints/meta.ts
+++ b/packages/backend/src/server/api/endpoints/meta.ts
@@ -4,7 +4,6 @@ import type { AdsRepository, EmojisRepository, UsersRepository } from '@/models/
 import { MAX_NOTE_TEXT_LENGTH, DB_MAX_NOTE_TEXT_LENGTH } from '@/const.js';
 import { Endpoint } from '@/server/api/endpoint-base.js';
 import { UserEntityService } from '@/core/entities/UserEntityService.js';
-import { EmojiEntityService } from '@/core/entities/EmojiEntityService.js';
 import { MetaService } from '@/core/MetaService.js';
 import type { Config } from '@/config.js';
 import { DI } from '@/di-symbols.js';
@@ -152,43 +151,6 @@ export const meta = {
 				type: 'number',
 				optional: false, nullable: false,
 			},
-			emojis: {
-				type: 'array',
-				optional: false, nullable: false,
-				items: {
-					type: 'object',
-					optional: false, nullable: false,
-					properties: {
-						id: {
-							type: 'string',
-							optional: false, nullable: false,
-							format: 'id',
-						},
-						aliases: {
-							type: 'array',
-							optional: false, nullable: false,
-							items: {
-								type: 'string',
-								optional: false, nullable: false,
-							},
-						},
-						category: {
-							type: 'string',
-							optional: false, nullable: true,
-						},
-						host: {
-							type: 'string',
-							optional: false, nullable: true,
-							description: 'The local host is represented with `null`.',
-						},
-						url: {
-							type: 'string',
-							optional: false, nullable: false,
-							format: 'url',
-						},
-					},
-				},
-			},
 			ads: {
 				type: 'array',
 				optional: false, nullable: false,
@@ -326,30 +288,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 		@Inject(DI.adsRepository)
 		private adsRepository: AdsRepository,
 
-		@Inject(DI.emojisRepository)
-		private emojisRepository: EmojisRepository,
-
 		private userEntityService: UserEntityService,
-		private emojiEntityService: EmojiEntityService,
 		private metaService: MetaService,
 	) {
 		super(meta, paramDef, async (ps, me) => {
 			const instance = await this.metaService.fetch(true);
 
-			const emojis = await this.emojisRepository.find({
-				where: {
-					host: IsNull(),
-				},
-				order: {
-					category: 'ASC',
-					name: 'ASC',
-				},
-				cache: {
-					id: 'meta_emojis',
-					milliseconds: 3600000,	// 1 hour
-				},
-			});
-
 			const ads = await this.adsRepository.find({
 				where: {
 					expiresAt: MoreThan(new Date()),
@@ -390,7 +334,6 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
 				backgroundImageUrl: instance.backgroundImageUrl,
 				logoImageUrl: instance.logoImageUrl,
 				maxNoteTextLength: MAX_NOTE_TEXT_LENGTH, // 後方互換性のため
-				emojis: await this.emojiEntityService.packMany(emojis),
 				defaultLightTheme: instance.defaultLightTheme,
 				defaultDarkTheme: instance.defaultDarkTheme,
 				ads: ads.map(ad => ({
diff --git a/packages/frontend/src/components/MkAutocomplete.vue b/packages/frontend/src/components/MkAutocomplete.vue
index 8ed60bc5dc..0d0c5edbae 100644
--- a/packages/frontend/src/components/MkAutocomplete.vue
+++ b/packages/frontend/src/components/MkAutocomplete.vue
@@ -47,6 +47,9 @@ import { emojilist } from '@/scripts/emojilist';
 import { instance } from '@/instance';
 import { i18n } from '@/i18n';
 import { miLocalStorage } from '@/local-storage';
+import { getCustomEmojis } from '@/custom-emojis';
+
+const customEmojis = await getCustomEmojis();
 
 type EmojiDef = {
 	emoji: string;
@@ -86,7 +89,6 @@ for (const x of lib) {
 emjdb.sort((a, b) => a.name.length - b.name.length);
 
 //#region Construct Emoji DB
-const customEmojis = instance.emojis;
 const emojiDefinitions: EmojiDef[] = [];
 
 for (const x of customEmojis) {
@@ -117,7 +119,6 @@ export default {
 	emojiDb,
 	emojiDefinitions,
 	emojilist,
-	customEmojis,
 };
 </script>
 
diff --git a/packages/frontend/src/components/MkEmojiPicker.vue b/packages/frontend/src/components/MkEmojiPicker.vue
index f3b3ac0b50..8df01f6c25 100644
--- a/packages/frontend/src/components/MkEmojiPicker.vue
+++ b/packages/frontend/src/components/MkEmojiPicker.vue
@@ -6,7 +6,7 @@
 			<div v-if="searchResultCustom.length > 0" class="body">
 				<button
 					v-for="emoji in searchResultCustom"
-					:key="emoji.id"
+					:key="emoji.name"
 					class="_button item"
 					:title="emoji.name"
 					tabindex="0"
@@ -85,9 +85,10 @@ import MkRippleEffect from '@/components/MkRippleEffect.vue';
 import * as os from '@/os';
 import { isTouchUsing } from '@/scripts/touch';
 import { deviceKind } from '@/scripts/device-kind';
-import { emojiCategories, instance } from '@/instance';
+import { instance } from '@/instance';
 import { i18n } from '@/i18n';
 import { defaultStore } from '@/store';
+import { getCustomEmojiCategories, getCustomEmojis } from '@/custom-emojis';
 
 const props = withDefaults(defineProps<{
 	showPinned?: boolean;
@@ -103,6 +104,7 @@ const emit = defineEmits<{
 	(ev: 'chosen', v: string): void;
 }>();
 
+const customEmojis = await getCustomEmojis();
 const search = shallowRef<HTMLInputElement>();
 const emojis = shallowRef<HTMLDivElement>();
 
@@ -118,8 +120,7 @@ const {
 const size = computed(() => props.asReactionPicker ? reactionPickerSize.value : 1);
 const width = computed(() => props.asReactionPicker ? reactionPickerWidth.value : 3);
 const height = computed(() => props.asReactionPicker ? reactionPickerHeight.value : 2);
-const customEmojiCategories = emojiCategories;
-const customEmojis = instance.emojis;
+const customEmojiCategories = await getCustomEmojiCategories();
 const q = ref<string>('');
 const searchResultCustom = ref<Misskey.entities.CustomEmoji[]>([]);
 const searchResultUnicode = ref<UnicodeEmojiDef[]>([]);
diff --git a/packages/frontend/src/custom-emojis.ts b/packages/frontend/src/custom-emojis.ts
new file mode 100644
index 0000000000..2a52753f84
--- /dev/null
+++ b/packages/frontend/src/custom-emojis.ts
@@ -0,0 +1,48 @@
+import { api } from './os';
+import { miLocalStorage } from './local-storage';
+
+const storageCache = miLocalStorage.getItem('emojis');
+let cached = storageCache ? JSON.parse(storageCache) : null;
+export async function getCustomEmojis() {
+	const now = Date.now();
+	const lastFetchedAt = miLocalStorage.getItem('lastEmojisFetchedAt');
+	if (cached && lastFetchedAt && (now - parseInt(lastFetchedAt)) < 1000 * 60 * 60) return cached;
+
+	const res = await api('emojis', {});
+
+	cached = res.emojis;
+	miLocalStorage.setItem('emojis', JSON.stringify(cached));
+	miLocalStorage.setItem('lastEmojisFetchedAt', now.toString());
+}
+
+let cachedCategories;
+export async function getCustomEmojiCategories() {
+	if (cachedCategories) return cachedCategories;
+
+	const customEmojis = await getCustomEmojis();
+
+	const categories = new Set();
+	for (const emoji of customEmojis) {
+		categories.add(emoji.category);
+	}
+	const res = Array.from(categories);
+	cachedCategories = res;
+	return res;
+}
+
+let cachedTags;
+export async function getCustomEmojiTags() {
+	if (cachedTags) return cachedTags;
+
+	const customEmojis = await getCustomEmojis();
+
+	const tags = new Set();
+	for (const emoji of customEmojis) {
+		for (const tag of emoji.aliases) {
+			tags.add(tag);
+		}
+	}
+	const res = Array.from(tags);
+	cachedTags = res;
+	return res;
+}
diff --git a/packages/frontend/src/instance.ts b/packages/frontend/src/instance.ts
index 82d3e7aea2..08dbd9737c 100644
--- a/packages/frontend/src/instance.ts
+++ b/packages/frontend/src/instance.ts
@@ -5,11 +5,11 @@ import { miLocalStorage } from './local-storage';
 
 // TODO: 他のタブと永続化されたstateを同期
 
-const instanceData = miLocalStorage.getItem('instance');
+const cached = miLocalStorage.getItem('instance');
 
 // TODO: instanceをリアクティブにするかは再考の余地あり
 
-export const instance: Misskey.entities.InstanceMetadata = reactive(instanceData ? JSON.parse(instanceData) : {
+export const instance: Misskey.entities.InstanceMetadata = reactive(cached ? JSON.parse(cached) : {
 	// TODO: set default values
 });
 
@@ -24,23 +24,3 @@ export async function fetchInstance() {
 
 	miLocalStorage.setItem('instance', JSON.stringify(instance));
 }
-
-export const emojiCategories = computed(() => {
-	if (instance.emojis == null) return [];
-	const categories = new Set();
-	for (const emoji of instance.emojis) {
-		categories.add(emoji.category);
-	}
-	return Array.from(categories);
-});
-
-export const emojiTags = computed(() => {
-	if (instance.emojis == null) return [];
-	const tags = new Set();
-	for (const emoji of instance.emojis) {
-		for (const tag of emoji.aliases) {
-			tags.add(tag);
-		}
-	}
-	return Array.from(tags);
-});
diff --git a/packages/frontend/src/local-storage.ts b/packages/frontend/src/local-storage.ts
index 50e28d621f..bb8192e980 100644
--- a/packages/frontend/src/local-storage.ts
+++ b/packages/frontend/src/local-storage.ts
@@ -2,6 +2,8 @@ type Keys =
 	'v' |
 	'lastVersion' |
 	'instance' |
+	'emojis' | // TODO: indexed db
+	'lastEmojisFetchedAt' |
 	'account' |
 	'accounts' |
 	'latestDonationInfoShownAt' |
diff --git a/packages/frontend/src/pages/about.emojis.vue b/packages/frontend/src/pages/about.emojis.vue
index e15a2b1bdf..acf6237c87 100644
--- a/packages/frontend/src/pages/about.emojis.vue
+++ b/packages/frontend/src/pages/about.emojis.vue
@@ -7,7 +7,7 @@
 
 		<!-- たくさんあると邪魔
 		<div class="tags">
-			<span class="tag _button" v-for="tag in tags" :class="{ active: selectedTags.has(tag) }" @click="toggleTag(tag)">{{ tag }}</span>
+			<span class="tag _button" v-for="tag in customEmojiTags" :class="{ active: selectedTags.has(tag) }" @click="toggleTag(tag)">{{ tag }}</span>
 		</div>
 		-->
 	</div>
@@ -28,8 +28,8 @@
 </div>
 </template>
 
-<script lang="ts">
-import { defineComponent, computed } from 'vue';
+<script lang="ts" setup>
+import { defineComponent, computed, watch } from 'vue';
 import XEmoji from './emojis.emoji.vue';
 import MkButton from '@/components/MkButton.vue';
 import MkInput from '@/components/MkInput.vue';
@@ -37,62 +37,43 @@ import MkSelect from '@/components/MkSelect.vue';
 import MkFoldableSection from '@/components/MkFoldableSection.vue';
 import MkTab from '@/components/MkTab.vue';
 import * as os from '@/os';
-import { emojiCategories, emojiTags } from '@/instance';
+import { getCustomEmojis, getCustomEmojiCategories, getCustomEmojiTags } from '@/custom-emojis';
 
-export default defineComponent({
-	components: {
-		MkButton,
-		MkInput,
-		MkSelect,
-		MkFoldableSection,
-		MkTab,
-		XEmoji,
-	},
+const customEmojis = await getCustomEmojis();
+const customEmojiCategories = await getCustomEmojiCategories();
+const customEmojiTags = await getCustomEmojiTags();
+let q = $ref('');
+let searchEmojis = $ref(null);
+let selectedTags = $ref(new Set());
 
-	data() {
-		return {
-			q: '',
-			customEmojiCategories: emojiCategories,
-			customEmojis: this.$instance.emojis,
-			tags: emojiTags,
-			selectedTags: new Set(),
-			searchEmojis: null,
-		};
-	},
+function search() {
+	if ((q === '' || q == null) && selectedTags.size === 0) {
+		searchEmojis = null;
+		return;
+	}
 
-	watch: {
-		q() { this.search(); },
-		selectedTags: {
-			handler() {
-				this.search();
-			},
-			deep: true,
-		},
-	},
+	if (selectedTags.size === 0) {
+		searchEmojis = customEmojis.filter(emoji => emoji.name.includes(q) || emoji.aliases.includes(q));
+	} else {
+		searchEmojis = customEmojis.filter(emoji => (emoji.name.includes(q) || emoji.aliases.includes(q)) && [...selectedTags].every(t => emoji.aliases.includes(t)));
+	}
+}
 
-	methods: {
-		search() {
-			if ((this.q === '' || this.q == null) && this.selectedTags.size === 0) {
-				this.searchEmojis = null;
-				return;
-			}
+function toggleTag(tag) {
+	if (selectedTags.has(tag)) {
+		selectedTags.delete(tag);
+	} else {
+		selectedTags.add(tag);
+	}
+}
 
-			if (this.selectedTags.size === 0) {
-				this.searchEmojis = this.customEmojis.filter(emoji => emoji.name.includes(this.q) || emoji.aliases.includes(this.q));
-			} else {
-				this.searchEmojis = this.customEmojis.filter(emoji => (emoji.name.includes(this.q) || emoji.aliases.includes(this.q)) && [...this.selectedTags].every(t => emoji.aliases.includes(t)));
-			}
-		},
-
-		toggleTag(tag) {
-			if (this.selectedTags.has(tag)) {
-				this.selectedTags.delete(tag);
-			} else {
-				this.selectedTags.add(tag);
-			}
-		},
-	},
+watch($$(q), () => {
+	search();
 });
+
+watch($$(selectedTags), () => {
+	search();
+}, { deep: true });
 </script>
 
 <style lang="scss" scoped>
diff --git a/packages/frontend/src/pages/admin/emoji-edit-dialog.vue b/packages/frontend/src/pages/admin/emoji-edit-dialog.vue
index c0a997d7b4..0b6a5e1557 100644
--- a/packages/frontend/src/pages/admin/emoji-edit-dialog.vue
+++ b/packages/frontend/src/pages/admin/emoji-edit-dialog.vue
@@ -36,7 +36,7 @@ import MkInput from '@/components/MkInput.vue';
 import * as os from '@/os';
 import { unique } from '@/scripts/array';
 import { i18n } from '@/i18n';
-import { emojiCategories } from '@/instance';
+import { getCustomEmojiCategories } from '@/custom-emojis';
 
 const props = defineProps<{
 	emoji: any,
@@ -46,7 +46,7 @@ let dialog = $ref(null);
 let name: string = $ref(props.emoji.name);
 let category: string = $ref(props.emoji.category);
 let aliases: string = $ref(props.emoji.aliases.join(' '));
-let categories: string[] = $ref(emojiCategories);
+const categories = await getCustomEmojiCategories();
 
 const emit = defineEmits<{
 	(ev: 'done', v: { deleted?: boolean, updated?: any }): void,
diff --git a/packages/frontend/src/pages/admin/overview.stats.vue b/packages/frontend/src/pages/admin/overview.stats.vue
index 43a735cbf9..08f31676f3 100644
--- a/packages/frontend/src/pages/admin/overview.stats.vue
+++ b/packages/frontend/src/pages/admin/overview.stats.vue
@@ -36,7 +36,7 @@
 				<div class="icon"><i class="ti ti-icons"></i></div>
 				<div class="body">
 					<div class="value">
-						<MkNumber :value="$instance.emojis.length" style="margin-right: 0.5em;"/>
+						<MkNumber :value="customEmojis.length" style="margin-right: 0.5em;"/>
 					</div>
 					<div class="label">Custom emojis</div>
 				</div>
@@ -63,6 +63,9 @@ import number from '@/filters/number';
 import MkNumberDiff from '@/components/MkNumberDiff.vue';
 import MkNumber from '@/components/MkNumber.vue';
 import { i18n } from '@/i18n';
+import { getCustomEmojis } from '@/custom-emojis';
+
+const customEmojis = await getCustomEmojis();
 
 let stats: any = $ref(null);
 let usersComparedToThePrevDay = $ref<number>();
diff --git a/packages/frontend/src/pages/mfm-cheat-sheet.vue b/packages/frontend/src/pages/mfm-cheat-sheet.vue
index 697a692743..f49b6959c8 100644
--- a/packages/frontend/src/pages/mfm-cheat-sheet.vue
+++ b/packages/frontend/src/pages/mfm-cheat-sheet.vue
@@ -317,12 +317,15 @@ import MkTextarea from '@/components/MkTextarea.vue';
 import { definePageMetadata } from '@/scripts/page-metadata';
 import { i18n } from '@/i18n';
 import { instance } from '@/instance';
+import { getCustomEmojis } from '@/custom-emojis';
+
+const customEmojis = await getCustomEmojis();
 
 let preview_mention = $ref('@example');
 let preview_hashtag = $ref('#test');
 let preview_url = $ref('https://example.com');
 let preview_link = $ref(`[${i18n.ts._mfm.dummy}](https://example.com)`);
-let preview_emoji = $ref(instance.emojis.length ? `:${instance.emojis[0].name}:` : ':emojiname:');
+let preview_emoji = $ref(customEmojis.length ? `:${customEmojis[0].name}:` : ':emojiname:');
 let preview_bold = $ref(`**${i18n.ts._mfm.dummy}**`);
 let preview_small = $ref(`<small>${i18n.ts._mfm.dummy}</small>`);
 let preview_center = $ref(`<center>${i18n.ts._mfm.dummy}</center>`);
diff --git a/packages/frontend/src/pages/settings/index.vue b/packages/frontend/src/pages/settings/index.vue
index 3468d44e00..e1e050ee70 100644
--- a/packages/frontend/src/pages/settings/index.vue
+++ b/packages/frontend/src/pages/settings/index.vue
@@ -183,6 +183,8 @@ const menuDef = computed(() => [{
 		action: () => {
 			miLocalStorage.removeItem('locale');
 			miLocalStorage.removeItem('theme');
+			miLocalStorage.removeItem('emojis');
+			miLocalStorage.removeItem('lastEmojisFetchedAt');
 			unisonReload();
 		},
 	}, {