diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 55a0247b81df419def6f8c273ba5ffffce26811e..cbbb8957517c1d66eeeaac0e4e99ed41a45ac4fd 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -41,6 +41,7 @@ Fixed
 * Phone numbers couldn't be in regional format.
 * System status view wasn't accessible through new frontend if a check failed.
 * Progress page didn't show error message on failure.
+* Dynamic routes were not removed/hid when the respective object registering it was deleted.
 
 `3.0b3`_ - 2023-03-19
 ---------------------
diff --git a/aleksis/core/frontend/components/app/App.vue b/aleksis/core/frontend/components/app/App.vue
index 6db2abd0a882802156a269ec6ae24462615bd918..94dc5ebc0964398d5ee4ee04dbe2ba556c902b33 100644
--- a/aleksis/core/frontend/components/app/App.vue
+++ b/aleksis/core/frontend/components/app/App.vue
@@ -283,7 +283,7 @@ export default {
     },
     $route: {
       handler(newRoute) {
-        if (newRoute.matched.length === 0) {
+        if (newRoute.matched.length === 0 || newRoute.meta.hide) {
           this.error404 = true;
         } else {
           this.error404 = false;
diff --git a/aleksis/core/frontend/mixins/menus.js b/aleksis/core/frontend/mixins/menus.js
index ee07678848c93436fc15f4f015b056f7a7728aa1..9ba58bcaa84e72917e3057614fca6058df39af3a 100644
--- a/aleksis/core/frontend/mixins/menus.js
+++ b/aleksis/core/frontend/mixins/menus.js
@@ -55,7 +55,8 @@ const menusMixin = {
             : true) &&
           (route.meta.validators
             ? this.checkValidators(route.meta.validators)
-            : true)
+            : true) &&
+          !route.meta.hide
         ) {
           let menuItem = {
             ...route.meta,
@@ -83,7 +84,8 @@ const menusMixin = {
             : true) &&
           (route.meta.validators
             ? this.checkValidators(route.meta.validators)
-            : true)
+            : true) &&
+          !route.meta.hide
         ) {
           let menuItem = {
             ...route.meta,
diff --git a/aleksis/core/frontend/mixins/routes.js b/aleksis/core/frontend/mixins/routes.js
index 813edd5777e9868680d5a5d9e8e495d70ef35790..9adbdafc7426fcc19174f91266b978471f3a38e9 100644
--- a/aleksis/core/frontend/mixins/routes.js
+++ b/aleksis/core/frontend/mixins/routes.js
@@ -14,7 +14,7 @@ const routesMixin = {
   apollo: {
     dynamicRoutes: {
       query: gqlDynamicRoutes,
-      pollInterval: 60000,
+      pollInterval: 10000,
     },
   },
   watch: {
@@ -38,6 +38,8 @@ const routesMixin = {
                 menuPermission: route.menuPermission,
                 permission: route.routePermission,
                 newTab: route.menuNewTab,
+                dynamic: true,
+                hide: false,
               },
             };
 
@@ -49,6 +51,17 @@ const routesMixin = {
           }
         }
 
+        for (const route of this.$router
+          .getRoutes()
+          .filter((r) => r.meta.dynamic && !r.meta.hide)) {
+          if (
+            !(newDynamicRoutes.map((r) => r.routeName).indexOf(route.name) > -1)
+          ) {
+            let hiddenRoute = { ...route, meta: { ...route.meta, hide: true } };
+            this.$router.addRoute(hiddenRoute);
+          }
+        }
+
         this.getPermissionNames();
         this.buildMenus();
       },