diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue
index 5c0fa60847..67b3165ade 100644
--- a/packages/frontend/src/components/MkPageWindow.vue
+++ b/packages/frontend/src/components/MkPageWindow.vue
@@ -45,6 +45,7 @@ import { claimAchievement } from '@/utility/achievements.js';
 import { useRouterFactory } from '@/router/supplier.js';
 import { mainRouter } from '@/router/main.js';
 import { analytics } from '@/analytics.js';
+import { DI } from '@/di.js';
 
 const props = defineProps<{
 	initialPath: string;
@@ -119,7 +120,7 @@ windowRouter.addListener('change', ctx => {
 
 windowRouter.init();
 
-provide('router', windowRouter);
+provide(DI.router, windowRouter);
 provide('inAppSearchMarkerId', searchMarkerId);
 provideMetadataReceiver((metadataGetter) => {
 	const info = metadataGetter();
diff --git a/packages/frontend/src/components/global/RouterView.vue b/packages/frontend/src/components/global/RouterView.vue
index 2e963daa27..25a29a4ae7 100644
--- a/packages/frontend/src/components/global/RouterView.vue
+++ b/packages/frontend/src/components/global/RouterView.vue
@@ -24,20 +24,21 @@ import type { IRouter, Resolved, RouteDef } from '@/nirax.js';
 import { prefer } from '@/preferences.js';
 import { globalEvents } from '@/events.js';
 import MkLoadingPage from '@/pages/_loading_.vue';
+import { DI } from '@/di.js';
 
 const props = defineProps<{
 	router?: IRouter;
 	nested?: boolean;
 }>();
 
-const router = props.router ?? inject('router');
+const router = props.router ?? inject(DI.router);
 
 if (router == null) {
 	throw new Error('no router provided');
 }
 
-const currentDepth = inject('routerCurrentDepth', 0);
-provide('routerCurrentDepth', currentDepth + 1);
+const currentDepth = inject(DI.routerCurrentDepth, 0);
+provide(DI.routerCurrentDepth, currentDepth + 1);
 
 function resolveNested(current: Resolved, d = 0): Resolved | null {
 	if (!props.nested) return current;
diff --git a/packages/frontend/src/di.ts b/packages/frontend/src/di.ts
new file mode 100644
index 0000000000..538f85df2d
--- /dev/null
+++ b/packages/frontend/src/di.ts
@@ -0,0 +1,12 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import type { InjectionKey, Ref } from 'vue';
+import type { IRouter } from '@/nirax.js';
+
+export const DI = {
+	routerCurrentDepth: Symbol() as InjectionKey<number>,
+	router: Symbol() as InjectionKey<IRouter>,
+};
diff --git a/packages/frontend/src/router/supplier.ts b/packages/frontend/src/router/supplier.ts
index 87f8829854..191dd49ebb 100644
--- a/packages/frontend/src/router/supplier.ts
+++ b/packages/frontend/src/router/supplier.ts
@@ -4,16 +4,17 @@
  */
 
 import { inject } from 'vue';
-import { Router } from '@/nirax.js';
 import type { IRouter } from '@/nirax.js';
+import { Router } from '@/nirax.js';
 import { mainRouter } from '@/router/main.js';
+import { DI } from '@/di.js';
 
 /**
  * メインの{@link Router}を取得する。
  * あらかじめ{@link setupRouter}を実行しておく必要がある({@link provide}により{@link IRouter}のインスタンスを注入可能であるならばこの限りではない)
  */
 export function useRouter(): IRouter {
-	return inject<Router | null>('router', null) ?? mainRouter;
+	return inject<Router | null>(DI.router, null) ?? mainRouter;
 }
 
 /**
diff --git a/packages/frontend/src/ui/classic.vue b/packages/frontend/src/ui/classic.vue
index 3f6f74a6a9..becb219c24 100644
--- a/packages/frontend/src/ui/classic.vue
+++ b/packages/frontend/src/ui/classic.vue
@@ -60,6 +60,7 @@ import { i18n } from '@/i18n.js';
 import { miLocalStorage } from '@/local-storage.js';
 import { mainRouter } from '@/router/main.js';
 import { prefer } from '@/preferences.js';
+import { DI } from '@/di.js';
 
 const XHeaderMenu = defineAsyncComponent(() => import('./classic.header.vue'));
 const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue'));
@@ -80,7 +81,7 @@ const live2d = shallowRef<HTMLIFrameElement>();
 const widgetsLeft = ref<HTMLElement>();
 const widgetsRight = ref<HTMLElement>();
 
-provide('router', mainRouter);
+provide(DI.router, mainRouter);
 provideMetadataReceiver((metadataGetter) => {
 	const info = metadataGetter();
 	pageMetadata.value = info;
diff --git a/packages/frontend/src/ui/deck/main-column.vue b/packages/frontend/src/ui/deck/main-column.vue
index 282aa7c833..1ba01a4c8d 100644
--- a/packages/frontend/src/ui/deck/main-column.vue
+++ b/packages/frontend/src/ui/deck/main-column.vue
@@ -31,6 +31,7 @@ import { provideMetadataReceiver, provideReactiveMetadata } from '@/page.js';
 import { useScrollPositionManager } from '@/nirax.js';
 import { mainRouter } from '@/router/main.js';
 import { prefer } from '@/preferences.js';
+import { DI } from '@/di.js';
 
 defineProps<{
 	column: Column;
@@ -40,7 +41,7 @@ defineProps<{
 const contents = shallowRef<HTMLElement>();
 const pageMetadata = ref<null | PageMetadata>(null);
 
-provide('router', mainRouter);
+provide(DI.router, mainRouter);
 provideMetadataReceiver((metadataGetter) => {
 	const info = metadataGetter();
 	pageMetadata.value = info;
diff --git a/packages/frontend/src/ui/minimum.vue b/packages/frontend/src/ui/minimum.vue
index a590c29607..95d564f5a3 100644
--- a/packages/frontend/src/ui/minimum.vue
+++ b/packages/frontend/src/ui/minimum.vue
@@ -15,17 +15,18 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <script lang="ts" setup>
 import { computed, provide, ref } from 'vue';
-import XCommon from './_common_/common.vue';
-import { provideMetadataReceiver, provideReactiveMetadata } from '@/page.js';
-import type { PageMetadata } from '@/page.js';
 import { instanceName } from '@@/js/config.js';
+import XCommon from './_common_/common.vue';
+import type { PageMetadata } from '@/page.js';
+import { provideMetadataReceiver, provideReactiveMetadata } from '@/page.js';
 import { mainRouter } from '@/router/main.js';
+import { DI } from '@/di.js';
 
 const isRoot = computed(() => mainRouter.currentRoute.value.name === 'index');
 
 const pageMetadata = ref<null | PageMetadata>(null);
 
-provide('router', mainRouter);
+provide(DI.router, mainRouter);
 provideMetadataReceiver((metadataGetter) => {
 	const info = metadataGetter();
 	pageMetadata.value = info;
diff --git a/packages/frontend/src/ui/universal.vue b/packages/frontend/src/ui/universal.vue
index de1fff7e11..cb93b20c24 100644
--- a/packages/frontend/src/ui/universal.vue
+++ b/packages/frontend/src/ui/universal.vue
@@ -116,6 +116,7 @@ import { useScrollPositionManager } from '@/nirax.js';
 import { mainRouter } from '@/router/main.js';
 import { prefer } from '@/preferences.js';
 import { shouldSuggestRestoreBackup } from '@/preferences/utility.js';
+import { DI } from '@/di.js';
 
 const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue'));
 const XSidebar = defineAsyncComponent(() => import('@/ui/_common_/navbar.vue'));
@@ -140,7 +141,7 @@ const widgetsShowing = ref(false);
 const navFooter = shallowRef<HTMLElement>();
 const contents = shallowRef<InstanceType<typeof MkStickyContainer>>();
 
-provide('router', mainRouter);
+provide(DI.router, mainRouter);
 provideMetadataReceiver((metadataGetter) => {
 	const info = metadataGetter();
 	pageMetadata.value = info;
diff --git a/packages/frontend/src/ui/visitor.vue b/packages/frontend/src/ui/visitor.vue
index c885dd2a68..051bfbfa68 100644
--- a/packages/frontend/src/ui/visitor.vue
+++ b/packages/frontend/src/ui/visitor.vue
@@ -81,6 +81,7 @@ import { provideMetadataReceiver, provideReactiveMetadata } from '@/page.js';
 import { i18n } from '@/i18n.js';
 import MkVisitorDashboard from '@/components/MkVisitorDashboard.vue';
 import { mainRouter } from '@/router/main.js';
+import { DI } from '@/di.js';
 
 const isRoot = computed(() => mainRouter.currentRoute.value.name === 'index');
 
@@ -88,7 +89,7 @@ const DESKTOP_THRESHOLD = 1100;
 
 const pageMetadata = ref<null | PageMetadata>(null);
 
-provide('router', mainRouter);
+provide(DI.router, mainRouter);
 provideMetadataReceiver((metadataGetter) => {
 	const info = metadataGetter();
 	pageMetadata.value = info;
diff --git a/packages/frontend/src/ui/zen.vue b/packages/frontend/src/ui/zen.vue
index d64e5270c0..99248abecf 100644
--- a/packages/frontend/src/ui/zen.vue
+++ b/packages/frontend/src/ui/zen.vue
@@ -23,12 +23,13 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <script lang="ts" setup>
 import { computed, provide, ref } from 'vue';
-import XCommon from './_common_/common.vue';
-import { provideMetadataReceiver, provideReactiveMetadata } from '@/page.js';
-import type { PageMetadata } from '@/page.js';
 import { instanceName, ui } from '@@/js/config.js';
+import XCommon from './_common_/common.vue';
+import type { PageMetadata } from '@/page.js';
+import { provideMetadataReceiver, provideReactiveMetadata } from '@/page.js';
 import { i18n } from '@/i18n.js';
 import { mainRouter } from '@/router/main.js';
+import { DI } from '@/di.js';
 
 const isRoot = computed(() => mainRouter.currentRoute.value.name === 'index');
 
@@ -36,7 +37,7 @@ const pageMetadata = ref<null | PageMetadata>(null);
 
 const showBottom = !(new URLSearchParams(location.search)).has('zen') && ui === 'deck';
 
-provide('router', mainRouter);
+provide(DI.router, mainRouter);
 provideMetadataReceiver((metadataGetter) => {
 	const info = metadataGetter();
 	pageMetadata.value = info;