diff --git a/package-lock.json b/package-lock.json
index 4e1edb0232a123e64113e24ea628e0946a87f9db..c116ec695dab3d3df0c66bc547a687ea00fe8995 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -31,6 +31,7 @@
       },
       "devDependencies": {
         "@types/node": "^18.13.0",
+        "@types/node-polyglot": "^2.4.2",
         "@typescript-eslint/eslint-plugin": "^5.51.0",
         "@typescript-eslint/parser": "^5.51.0",
         "@vitejs/plugin-vue": "^4.0.0",
@@ -865,6 +866,12 @@
       "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==",
       "dev": true
     },
+    "node_modules/@types/node-polyglot": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/@types/node-polyglot/-/node-polyglot-2.4.2.tgz",
+      "integrity": "sha512-Tfx3TU/PBK8vW/BG1TK793EHlVpGnoHUj+DGxOwNOYwZiueLeu7FgksvDdpEyFSw4+AKKiEuiMm8EGUHUR4o6g==",
+      "dev": true
+    },
     "node_modules/@types/semver": {
       "version": "7.3.13",
       "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
@@ -6569,6 +6576,12 @@
       "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==",
       "dev": true
     },
+    "@types/node-polyglot": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/@types/node-polyglot/-/node-polyglot-2.4.2.tgz",
+      "integrity": "sha512-Tfx3TU/PBK8vW/BG1TK793EHlVpGnoHUj+DGxOwNOYwZiueLeu7FgksvDdpEyFSw4+AKKiEuiMm8EGUHUR4o6g==",
+      "dev": true
+    },
     "@types/semver": {
       "version": "7.3.13",
       "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
diff --git a/package.json b/package.json
index 269ec606252c299c1db5fa88fc0f2446d0c1b261..d11265f318dc5bd7057cf685c7865e97f48fff7e 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
   },
   "devDependencies": {
     "@types/node": "^18.13.0",
+    "@types/node-polyglot": "^2.4.2",
     "@typescript-eslint/eslint-plugin": "^5.51.0",
     "@typescript-eslint/parser": "^5.51.0",
     "@vitejs/plugin-vue": "^4.0.0",
diff --git a/src/i18n/index.js b/src/i18n/index.ts
similarity index 73%
rename from src/i18n/index.js
rename to src/i18n/index.ts
index bb5ff7f74e9e0655312de20278da141ecddd78a8..6f3499f4d643831cd55c1932b38ecf74d95064d5 100644
--- a/src/i18n/index.js
+++ b/src/i18n/index.ts
@@ -1,16 +1,16 @@
 import Polyglot from 'node-polyglot'
-import { computed, reactive } from 'vue'
+import { App, computed, reactive } from 'vue'
 import { has } from '@/utilities'
 
 const DEFAULT_LOCALE = import.meta.env.VUE_APP_DEFAULT_LOCALE ?? 'de'
 
 const locales = Object.fromEntries(
   Object.entries(import.meta.glob('./??.js', { import: 'default', eager: true })).map(
-    ([key, locale]) => [/([a-z]+)?.[jt]s$/.exec(key)[1], locale],
+    ([key, locale]) => [(/([a-z]+)?.[jt]s$/.exec(key) as string[])[1], locale],
   ),
 )
 
-function createPolyglot(locale) {
+function createPolyglot(locale: string) {
   return new Polyglot({ phrases: locales[locale] })
 }
 
@@ -29,18 +29,18 @@ const locale = computed({
 })
 const availableLocales = computed(() => Object.keys(locales))
 
-function t(phrase, context = {}) {
+function t(phrase: string, context = {}): string {
   return state.polyglot.t(phrase, context)
 }
 
 // IMHO this is not the best naming for this function, but it is consistent
 // with the vue-i18n library that most people working on vue applications
 // will be familiar with.
-function te(phrase) {
+function te(phrase: string): boolean {
   return state.polyglot.has(phrase)
 }
 
-function updateLocale(newLocale) {
+function updateLocale(newLocale: string): void {
   if (has(locales, newLocale)) {
     state.locale = newLocale
     state.polyglot = createPolyglot(newLocale)
@@ -63,10 +63,10 @@ export function useI18n() {
 }
 
 export const TranslationPlugin = {
-  install(Vue) {
-    Vue.prototype.$activeLocale = () => locale.value
-    Vue.prototype.$locale = updateLocale
-    Vue.prototype.$t = t
-    Vue.prototype.$te = te
+  install(app: App) {
+    app.config.globalProperties.$activeLocale = () => locale.value
+    app.config.globalProperties.$locale = updateLocale
+    app.config.globalProperties.$t = t
+    app.config.globalProperties.$te = te
   },
 }
diff --git a/tsconfig.json b/tsconfig.json
index 13200d61ce2eac9c033364e53ee7b5eef46be934..5765c9d61f5a26e41053c322d915bdb212d72870 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -11,7 +11,7 @@
     "resolveJsonModule": true,
     "esModuleInterop": true,
     "lib": ["esnext", "dom"],
-    "types": ["vite/client"],
+    "types": ["vite/client", "@types/node-polyglot"],
     "paths": {
       "@/*": ["src/*"]
     }