diff --git a/videoag_new_frontend/package-lock.json b/videoag_new_frontend/package-lock.json
index 1a09c9a8f3c19b07bb0afb7679d4fc96f7aa5fdc..c374a353595b9eecdd74e6220fcaf1d5755fbaf1 100644
--- a/videoag_new_frontend/package-lock.json
+++ b/videoag_new_frontend/package-lock.json
@@ -17,7 +17,6 @@
         "react-bootstrap": "^2.10.1",
         "react-dom": "^18.2.0",
         "react-markdown": "^9.0.1",
-        "react-router-dom": "^6.21.3",
         "react-toastify": "^10.0.5",
         "remark-gfm": "^4.0.0",
         "sass": "^1.68.0",
@@ -452,14 +451,6 @@
         "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
       }
     },
-    "node_modules/@remix-run/router": {
-      "version": "1.15.3",
-      "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz",
-      "integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==",
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
     "node_modules/@restart/hooks": {
       "version": "0.4.16",
       "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
@@ -5325,36 +5316,6 @@
         "react": ">=18"
       }
     },
-    "node_modules/react-router": {
-      "version": "6.22.3",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz",
-      "integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==",
-      "dependencies": {
-        "@remix-run/router": "1.15.3"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "peerDependencies": {
-        "react": ">=16.8"
-      }
-    },
-    "node_modules/react-router-dom": {
-      "version": "6.22.3",
-      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz",
-      "integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==",
-      "dependencies": {
-        "@remix-run/router": "1.15.3",
-        "react-router": "6.22.3"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      },
-      "peerDependencies": {
-        "react": ">=16.8",
-        "react-dom": ">=16.8"
-      }
-    },
     "node_modules/react-toastify": {
       "version": "10.0.5",
       "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz",
diff --git a/videoag_new_frontend/package.json b/videoag_new_frontend/package.json
index 522a4632efed7e303089a1d1e7cac5594198c6c8..90f38200c0749dbdb93b702fc650f24097480fce 100644
--- a/videoag_new_frontend/package.json
+++ b/videoag_new_frontend/package.json
@@ -24,7 +24,6 @@
     "react-bootstrap": "^2.10.1",
     "react-dom": "^18.2.0",
     "react-markdown": "^9.0.1",
-    "react-router-dom": "^6.21.3",
     "react-toastify": "^10.0.5",
     "remark-gfm": "^4.0.0",
     "sass": "^1.68.0",
diff --git a/videoag_new_frontend/src/components/CourseListing.tsx b/videoag_new_frontend/src/components/CourseListing.tsx
index 893b3806ef24c0832acc1065a0c7d71cb640ddbd..f832e42c1185fef23fa50fa198023e0ab0796d46 100644
--- a/videoag_new_frontend/src/components/CourseListing.tsx
+++ b/videoag_new_frontend/src/components/CourseListing.tsx
@@ -1,7 +1,5 @@
-import { useLoaderData } from "react-router-dom";
 import { useBackendContext } from "./BackendProvider";
 import Link from "next/link";
-import { Backend } from "@/api/Backend";
 import {
     OMCreate,
     OMDelete,
@@ -15,13 +13,7 @@ import Title from "./TitleComponent";
 import DownloadAllModal from "./DownloadManager";
 
 import type { GetCourseResponse, lecture } from "@/api/api_v1_types";
-
-export function getCourseDataLoader(api: Backend) {
-    const actualLoader = async ({ params }: { params: { course_id_string?: string } }) => {
-        return api.getCourse(params.course_id_string!, true);
-    };
-    return actualLoader;
-}
+import { ResourceType } from "@/misc/PromiseHelpers";
 
 function ListingHeader({ course }: { course: GetCourseResponse }) {
     const { editMode } = useEditMode();
@@ -330,8 +322,12 @@ function ListingBody({ course }: { course: GetCourseResponse }) {
     );
 }
 
-export default function CourseListing() {
-    const course = useLoaderData() as GetCourseResponse | undefined;
+export default function CourseListing({
+    courseData,
+}: {
+    courseData: ResourceType<GetCourseResponse>;
+}) {
+    const course = courseData.read()!;
 
     if (!course) return <>invalid course listing</>;
 
diff --git a/videoag_new_frontend/src/pages/dynamic_course_listing.tsx b/videoag_new_frontend/src/pages/dynamic_course_listing.tsx
index c6f0d4c32e906f1e81b7c70bae884962dcaa976d..fd95f5fff666240b97284d9e1bbe9d9f9fc6a58b 100644
--- a/videoag_new_frontend/src/pages/dynamic_course_listing.tsx
+++ b/videoag_new_frontend/src/pages/dynamic_course_listing.tsx
@@ -1,57 +1,54 @@
-import { useEffect, useState } from "react";
-import { RouterProvider, createBrowserRouter, useRouteError } from "react-router-dom";
-import nextConfig from "@/../basepath";
+import { Suspense, useEffect, useState } from "react";
 import Four04 from "./404";
-import CourseListing, { getCourseDataLoader } from "@/components/CourseListing";
+import CourseListing from "@/components/CourseListing";
 import { useBackendContext } from "@/components/BackendProvider";
 import { ReloadBoundary } from "@/components/ReloadBoundary";
 import { ErrorPage } from "@/misc/ErrorHandlers";
-
-function Custom404() {
-    const error = useRouteError();
-    return (
-        <ErrorPage
-            error={error}
-            objectName="Kurs"
-            expectedErrorCodes={[
-                "unauthorized",
-                "access_forbidden",
-                "unknown_object",
-                "rate_limited",
-            ]}
-        />
-    );
-}
+import { ResourceType, fetchDataWrapper } from "@/misc/PromiseHelpers";
+import { usePathname } from "next/navigation";
+import { useUserContext } from "@/components/UserDataProvider";
+import { GetCourseResponse } from "@/api/api_v1_types";
+import { FallbackErrorBoundary } from "@/components/FallbackErrorBoundary";
 
 function ActualRedirector() {
     const api = useBackendContext();
+    const userContext = useUserContext();
+    const hasUserInfo = userContext.hasUserInfo();
+    const pathname = usePathname();
+    const matchedParams = pathname.match(/^\/([a-z0-9_-]+)\/?$/);
+    const [courseData, setCourseData] = useState<ResourceType<GetCourseResponse>>();
 
-    const router = createBrowserRouter(
-        [
-            {
-                path: ":course_id_string",
-                loader: getCourseDataLoader(api),
-                errorElement: <Custom404 />,
-                element: <CourseListing />,
-            },
-            {
-                path: "404",
-                element: <Four04 />,
-            },
-            {
-                path: "*",
-                element: <>* matched dynamic_course_listing</>,
-            },
-        ],
-        { basename: nextConfig.basePath },
-    );
     const reload = () => {
-        router.navigate(".", { replace: true });
+        if (!matchedParams) return;
+        setCourseData(fetchDataWrapper(api.getCourse(matchedParams[1], true)));
     };
 
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+    useEffect(reload, [api, pathname, hasUserInfo]);
+
+    if (!matchedParams) return <Four04 title="Unbekannter Pfad" text="dynamic_course_listing" />;
+    if (!courseData) return <></>;
+
     return (
         <ReloadBoundary reloadFunc={reload}>
-            <RouterProvider router={router} />
+            <FallbackErrorBoundary
+                fallback={(e: any) => (
+                    <ErrorPage
+                        error={e}
+                        objectName="Kurs"
+                        expectedErrorCodes={[
+                            "unauthorized",
+                            "access_forbidden",
+                            "unknown_object",
+                            "rate_limited",
+                        ]}
+                    />
+                )}
+            >
+                <Suspense fallback={<div className="spinner-border" />}>
+                    <CourseListing courseData={courseData} />
+                </Suspense>
+            </FallbackErrorBoundary>
         </ReloadBoundary>
     );
 }