diff --git a/videoag_new_frontend/src/components/FallbackErrorBoundary.tsx b/videoag_new_frontend/src/components/FallbackErrorBoundary.tsx
index f2231555166ecfdb48272b398783396c3a45417a..7ddfe4bcb95bd0d02bf5f89710d67693ee3d1a97 100644
--- a/videoag_new_frontend/src/components/FallbackErrorBoundary.tsx
+++ b/videoag_new_frontend/src/components/FallbackErrorBoundary.tsx
@@ -13,7 +13,7 @@ export class FallbackErrorBoundary extends React.Component<any, { error?: any }>
     }
 
     componentDidCatch(error: any, info: ErrorInfo) {
-        console.error(error, info);
+        console.error("The following error was caught by FallbackErrorBoundary:", error, info);
     }
 
     clearError() {
diff --git a/videoag_new_frontend/src/components/Player.tsx b/videoag_new_frontend/src/components/Player.tsx
index 359228b3ad7caf2062cb15ae4cbac6b0a235b1ee..ce3b781815ff9f936a2e409a24d3ed5b46131c0b 100644
--- a/videoag_new_frontend/src/components/Player.tsx
+++ b/videoag_new_frontend/src/components/Player.tsx
@@ -1,8 +1,6 @@
 import { MouseEvent, useEffect, useRef, useState } from "react";
 import "video.js/dist/video-js.min.css";
 import "@silvermine/videojs-quality-selector/dist/css/quality-selector.css";
-import { Backend } from "@/api/Backend";
-import { useLoaderData, useNavigate, useParams } from "react-router-dom";
 import Link from "next/link";
 import { useBackendContext } from "./BackendProvider";
 import { timestampToString, stringToStyledHtml } from "@/misc/Formatting";
@@ -19,7 +17,6 @@ import { showError } from "@/misc/ErrorHandlers";
 
 import type React from "react";
 import {
-    AuthenticationStatusResponse,
     GetCourseResponse,
     authentication_method,
     authentication_methods,
@@ -28,33 +25,8 @@ import {
     lecture,
 } from "@/api/api_v1_types";
 import Dropdown from "react-bootstrap/Dropdown";
-
-export function getLectureDataLoader(api: Backend, hasUserInfo: boolean) {
-    const actualLoader = async ({
-        params,
-    }: {
-        params: { course_id_string?: string; lecture_id?: string };
-    }) => {
-        let course: GetCourseResponse = await api.getCourse(params.course_id_string!, true);
-        let lecture = course.lectures!.find((l) => l.id === parseInt(params.lecture_id!));
-        if (lecture === undefined) {
-            throw new Error("Lecture not found");
-        }
-
-        let perms: AuthenticationStatusResponse = {
-            authenticated_methods: ["public"],
-            is_lecture_authenticated: true,
-        };
-        if (
-            lecture.authentication_methods.includes("public") === false &&
-            lecture.authentication_methods.length > 0
-        ) {
-            perms = await api.getAuthenticationStatus({ lecture_id: lecture.id });
-        }
-        return { course, perms, loaderHadUserInfo: hasUserInfo };
-    };
-    return actualLoader;
-}
+import { ResourceType } from "@/misc/PromiseHelpers";
+import { PlayerData } from "@/pages/dynamic_player";
 
 function VideoPlayer({ lecture, className }: { lecture: lecture; className?: string }) {
     const videoRef = useRef<HTMLVideoElement>(null);
@@ -185,10 +157,17 @@ function VideoPlayer({ lecture, className }: { lecture: lecture; className?: str
     );
 }
 
-function KapitelPopover({ timeStr, closePop }: { timeStr: string; closePop: () => void }) {
+function KapitelPopover({
+    timeStr,
+    closePop,
+    lectureId,
+}: {
+    timeStr: string;
+    closePop: () => void;
+    lectureId: number;
+}) {
     const userContext = useUserContext();
     const api = useBackendContext();
-    const lecture_id = parseInt(useParams().lecture_id!);
     const reloadFunc = useReloadBoundary();
 
     const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
@@ -207,7 +186,7 @@ function KapitelPopover({ timeStr, closePop }: { timeStr: string; closePop: () =
         if (userContext.canEditStuff()) {
             api.createOMObject("chapter", {
                 parent_type: "lecture",
-                parent_id: lecture_id,
+                parent_id: lectureId,
                 values: {
                     start_time: time,
                     name: text,
@@ -222,7 +201,7 @@ function KapitelPopover({ timeStr, closePop }: { timeStr: string; closePop: () =
                     showError(e, "Unable to create chapter");
                 });
         } else {
-            api.suggestChapter(lecture_id, {
+            api.suggestChapter(lectureId, {
                 start_time: time,
                 name: text,
             })
@@ -277,7 +256,7 @@ function AuthorizeHelper({
     authed_methods: authentication_methods;
 }) {
     const api = useBackendContext();
-    const navigate = useNavigate();
+    const reloadFunc = useReloadBoundary();
     const [userPwErrorState, setUserPwErrorState] = useState();
     const userContext = useUserContext();
     const hasUserInfo = userContext.hasUserInfo();
@@ -285,9 +264,10 @@ function AuthorizeHelper({
     useEffect(() => {
         if (hasUserInfo === true) {
             // reload page when the user logs in
-            navigate(".", { replace: true });
+            reloadFunc();
         }
-    }, [navigate, hasUserInfo]);
+        // eslint-disable-next-line react-hooks/exhaustive-deps
+    }, [hasUserInfo]);
 
     const startOauth = (method: authentication_method) => {
         if (method !== "moodle" && method !== "rwth") return;
@@ -299,7 +279,7 @@ function AuthorizeHelper({
                     let popInterval = setInterval(() => {
                         if (pop.closed) {
                             clearInterval(popInterval);
-                            navigate(".", { replace: true });
+                            reloadFunc();
                         }
                     }, 100);
                 }
@@ -315,9 +295,7 @@ function AuthorizeHelper({
         let user = form.username.value;
         let pass = form.password.value;
         api.authenticatePassword({ username: user, password: pass, lecture_id: lecture.id })
-            .then((res) => {
-                navigate(".", { replace: true });
-            })
+            .then(reloadFunc)
             .catch((e) => {
                 setUserPwErrorState(e);
             });
@@ -573,14 +551,10 @@ export function DownloadSources({
     );
 }
 
-export function EmbeddedPlayer() {
-    const { course, perms } = useLoaderData() as {
-        course: GetCourseResponse;
-        perms: AuthenticationStatusResponse;
-    };
+export function EmbeddedPlayer({ playerData }: { playerData: ResourceType<PlayerData> }) {
+    const { course, perms, lectureId } = playerData.read()!;
 
-    let lecture_id = parseInt(useParams().lecture_id!);
-    const lecture = course.lectures!.find((l) => l.id === lecture_id)!;
+    const lecture = course.lectures!.find((l) => l.id === lectureId)!;
 
     useEffect(() => {
         import("video.js");
@@ -608,17 +582,12 @@ export function EmbeddedPlayer() {
     return <>{pageContent} </>;
 }
 
-export default function Player() {
+export default function Player({ playerData }: { playerData: ResourceType<PlayerData> }) {
+    const { course, lectureId, perms, loaderHadUserInfo } = playerData.read()!;
     const userContext = useUserContext();
     const hasUserInfo = userContext.hasUserInfo();
 
-    const { course, perms, loaderHadUserInfo } = useLoaderData() as {
-        course: GetCourseResponse;
-        perms: AuthenticationStatusResponse;
-        loaderHadUserInfo: boolean;
-    };
-    let lecture_id = parseInt(useParams().lecture_id!);
-    const lecture = course.lectures!.find((l) => l.id === lecture_id)!;
+    const lecture = course.lectures!.find((l) => l.id === lectureId)!;
 
     useEffect(() => {
         import("video.js");
@@ -645,7 +614,12 @@ export default function Player() {
             let tstr = timestampToString(timestamp);
 
             setPopContent(
-                <KapitelPopover timeStr={tstr} key={tstr} closePop={() => setShowPop(false)} />,
+                <KapitelPopover
+                    timeStr={tstr}
+                    key={tstr}
+                    closePop={() => setShowPop(false)}
+                    lectureId={lectureId}
+                />,
             );
             setShowPop(true);
         });
diff --git a/videoag_new_frontend/src/misc/ErrorHandlers.tsx b/videoag_new_frontend/src/misc/ErrorHandlers.tsx
index e507e3f098569293d3dc7328a50e10c7d9a86da6..1b1c3532e4aab8cbcdbe58144e2ed6895963e2bd 100644
--- a/videoag_new_frontend/src/misc/ErrorHandlers.tsx
+++ b/videoag_new_frontend/src/misc/ErrorHandlers.tsx
@@ -117,7 +117,7 @@ export function ErrorPage({
     }
     return (
         <div className="alert alert-danger" role="alert">
-            <h4 className="alert-heading">Ein unerwarteter Fehler hat dich besucht</h4>
+            <h4 className="alert-heading">Unerwarteter Fehler!</h4>
             <p>{mainMessage}</p>
             <div>
                 Falls das Problem länger bestehen sollte, schreib uns bitte eine Mail an{" "}
@@ -131,12 +131,13 @@ export function ErrorPage({
                             : "Seite auf welcher der Fehler aufgetreten ist"}
                     </li>
                     <li>Fehler: {error.message}</li>
-                    <li>evt. was du getan hast als der Fehler aufgetreten ist</li>
+                    <li>Was hast du getan bevor der Fehler aufgetreten ist?</li>
+                    <li>Wie kann man den Fehler reproduzieren?</li>
                 </ul>
                 Wir werden uns dann schnellst möglich darum kümmern.
             </div>
-            <button type="button" className="btn btn-success mb-2" onClick={reloadFunc}>
-                <span className="bi bi-arrow-counterclockwise" />
+            <button type="button" className="btn btn-success mt-2" onClick={reloadFunc}>
+                <span className="bi bi-arrow-counterclockwise me-1" />
                 Neuladen
             </button>
         </div>
diff --git a/videoag_new_frontend/src/pages/dynamic_embed.tsx b/videoag_new_frontend/src/pages/dynamic_embed.tsx
index 6129a954bd2a83f956e3c720eee710f12af6a000..9f28b15eb79c09a765a1ac5f8ca744a05d6fae1d 100644
--- a/videoag_new_frontend/src/pages/dynamic_embed.tsx
+++ b/videoag_new_frontend/src/pages/dynamic_embed.tsx
@@ -1,64 +1,8 @@
 import { useEffect, useState } from "react";
-import { RouterProvider, createBrowserRouter, useRouteError } from "react-router-dom";
-import nextConfig from "@/../basepath";
-import Four04 from "./404";
-import { EmbeddedPlayer, getLectureDataLoader } from "@/components/Player";
-import { useBackendContext } from "@/components/BackendProvider";
-import { ReloadBoundary } from "@/components/ReloadBoundary";
-import { ErrorPage } from "@/misc/ErrorHandlers";
-import { useUserContext } from "@/components/UserDataProvider";
-
-function Custom404() {
-    const error = useRouteError();
-    return (
-        <ErrorPage
-            error={error}
-            objectName="Vorlesung"
-            expectedErrorCodes={[
-                "unauthorized",
-                "access_forbidden",
-                "unknown_object",
-                "rate_limited",
-            ]}
-        />
-    );
-}
-
-function ActualRedirector() {
-    const api = useBackendContext();
-    const userContext = useUserContext();
-
-    const router = createBrowserRouter(
-        [
-            {
-                path: ":course_id_string/:lecture_id/embed",
-                loader: getLectureDataLoader(api, userContext.hasUserInfo()),
-                errorElement: <Custom404 />,
-                element: <EmbeddedPlayer />,
-            },
-            {
-                path: "404",
-                element: <Four04 />,
-            },
-            {
-                path: "*",
-                element: <>* matched dynamic_embed</>,
-            },
-        ],
-        { basename: nextConfig.basePath },
-    );
-
-    const reload = () => {
-        router.navigate(".", { replace: true });
-    };
-
-    return (
-        <ReloadBoundary reloadFunc={reload}>
-            <RouterProvider router={router} />
-        </ReloadBoundary>
-    );
-}
+import { ActualRedirector } from "./dynamic_player";
 
+// This only exists, so that we can effectively differentiate between player and embed in DefaultLayout.tsx (to remove the page header/footer for embeds)
+// Necessary so that we can render the correct layout while building the page (since we can't use the actual pathname at build time)
 export default function DynamicEmbed() {
     // The following is a hack to force nextjs to not pre-render this page at build time (which obv wouldnt make sense)
     const [clientsideForcer, setClientsideForcer] = useState(false);
diff --git a/videoag_new_frontend/src/pages/dynamic_player.tsx b/videoag_new_frontend/src/pages/dynamic_player.tsx
index d78ab9615a5a0d038fb4262b0823a0377dc0fbbd..e64327472dce6e5195bd497f5b2af2bf07fcaaec 100644
--- a/videoag_new_frontend/src/pages/dynamic_player.tsx
+++ b/videoag_new_frontend/src/pages/dynamic_player.tsx
@@ -1,60 +1,99 @@
-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 Player, { getLectureDataLoader } from "@/components/Player";
+
 import { useBackendContext } from "@/components/BackendProvider";
 import { ReloadBoundary } from "@/components/ReloadBoundary";
-import { ErrorPage } from "@/misc/ErrorHandlers";
 import { useUserContext } from "@/components/UserDataProvider";
+import { usePathname } from "next/navigation";
+import { Backend } from "@/api/Backend";
+import { AuthenticationStatusResponse, GetCourseResponse } from "@/api/api_v1_types";
+import { ResourceType, fetchDataWrapper } from "@/misc/PromiseHelpers";
+import Player, { EmbeddedPlayer } from "@/components/Player";
+import { ErrorPage } from "@/misc/ErrorHandlers";
+import { FallbackErrorBoundary } from "@/components/FallbackErrorBoundary";
 
-function Custom404() {
-    const error = useRouteError();
-    return (
-        <ErrorPage
-            error={error}
-            objectName="Vorlesung"
-            expectedErrorCodes={[
-                "unauthorized",
-                "access_forbidden",
-                "unknown_object",
-                "rate_limited",
-            ]}
-        />
-    );
+export interface PlayerData {
+    course: GetCourseResponse;
+    perms: AuthenticationStatusResponse;
+    loaderHadUserInfo: boolean;
+    lectureId: number;
 }
 
-function ActualRedirector() {
+async function dataLoader(
+    api: Backend,
+    course_id_string: string,
+    lecture_id: string,
+    hasUserInfo: boolean,
+): Promise<PlayerData> {
+    let course: GetCourseResponse = await api.getCourse(course_id_string, true);
+    let lecture = course.lectures!.find((l) => l.id === parseInt(lecture_id));
+    if (lecture === undefined) {
+        throw new Error("Lecture not found");
+    }
+
+    let perms: AuthenticationStatusResponse = {
+        authenticated_methods: ["public"],
+        is_lecture_authenticated: true,
+    };
+    if (
+        lecture.authentication_methods.includes("public") === false &&
+        lecture.authentication_methods.length > 0
+    ) {
+        perms = await api.getAuthenticationStatus({ lecture_id: lecture.id });
+    }
+    return { course, perms, loaderHadUserInfo: hasUserInfo, lectureId: parseInt(lecture_id) };
+}
+
+// This redirector handles both the regular player and the embedded player
+export function ActualRedirector() {
     const api = useBackendContext();
     const userContext = useUserContext();
+    const hasUserInfo = userContext.hasUserInfo();
+    const pathname = usePathname();
+    const matchedParamsPlayer = pathname.match(/^\/([a-z0-9_-]+)\/([a-z0-9_-]+)$/);
+    const matchedParamsEmbed = pathname.match(/^\/([a-z0-9_-]+)\/([a-z0-9_-]+)\/embed$/);
+    const [playerData, setPlayerData] = useState<ResourceType<PlayerData>>();
 
-    const router = createBrowserRouter(
-        [
-            {
-                path: ":course_id_string/:lecture_id",
-                loader: getLectureDataLoader(api, userContext.hasUserInfo()),
-                errorElement: <Custom404 />,
-                element: <Player />,
-            },
-            {
-                path: "404",
-                element: <Four04 />,
-            },
-            {
-                path: "*",
-                element: <>* matched dynamic_player</>,
-            },
-        ],
-        { basename: nextConfig.basePath },
-    );
-
-    const reload = () => {
-        router.navigate(".", { replace: true });
+    const reloadData = () => {
+        if (!matchedParamsPlayer && !matchedParamsEmbed) return;
+        const matched = (matchedParamsPlayer ?? matchedParamsEmbed)!;
+        const courseId = matched[1];
+        const lectureId = matched[2];
+        setPlayerData(
+            fetchDataWrapper(dataLoader(api, courseId, lectureId, userContext.hasUserInfo())),
+        );
     };
 
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+    useEffect(reloadData, [api, hasUserInfo, pathname]);
+
+    if (!matchedParamsPlayer && !matchedParamsEmbed)
+        return <Four04 title="Unbekannter Pfad" text="dynamic_player" />;
+    if (matchedParamsPlayer && matchedParamsEmbed)
+        throw new Error("Both matchedParamsPlayer and matchedParamsEmbed are true");
+    if (!playerData) return <></>;
+
     return (
-        <ReloadBoundary reloadFunc={reload}>
-            <RouterProvider router={router} />
+        <ReloadBoundary reloadFunc={reloadData}>
+            <FallbackErrorBoundary
+                fallback={(e: any) => (
+                    <ErrorPage
+                        error={e}
+                        objectName="Vorlesung"
+                        expectedErrorCodes={[
+                            "unauthorized",
+                            "access_forbidden",
+                            "unknown_object",
+                            "rate_limited",
+                        ]}
+                    />
+                )}
+            >
+                <Suspense fallback={<div className="spinner-border" />}>
+                    {matchedParamsEmbed && <EmbeddedPlayer playerData={playerData} />}
+                    {matchedParamsPlayer && <Player playerData={playerData} />}
+                </Suspense>
+            </FallbackErrorBoundary>
         </ReloadBoundary>
     );
 }