diff --git a/src/app/auth/page.tsx b/src/app/auth/page.tsx
new file mode 100644
index 00000000..3a2b056d
--- /dev/null
+++ b/src/app/auth/page.tsx
@@ -0,0 +1,9 @@
+import CallbackPage from "@/auth/CallbackPage";
+
+/**
+ * OIDC authentication callback route.
+ * This page handles the redirect from the identity provider after user authentication.
+ */
+export default function AuthCallbackPage() {
+ return ;
+}
diff --git a/src/app/silent-auth/page.tsx b/src/app/silent-auth/page.tsx
new file mode 100644
index 00000000..99d8cbc3
--- /dev/null
+++ b/src/app/silent-auth/page.tsx
@@ -0,0 +1,9 @@
+import CallbackPage from "@/auth/CallbackPage";
+
+/**
+ * OIDC silent authentication callback route.
+ * This page handles silent token renewal redirects from the identity provider.
+ */
+export default function SilentAuthCallbackPage() {
+ return ;
+}
diff --git a/src/auth/CallbackPage.tsx b/src/auth/CallbackPage.tsx
new file mode 100644
index 00000000..d4cfdd42
--- /dev/null
+++ b/src/auth/CallbackPage.tsx
@@ -0,0 +1,29 @@
+"use client";
+
+import FullScreenLoading from "@components/ui/FullScreenLoading";
+import { useRouter } from "next/navigation";
+import { useEffect } from "react";
+
+/**
+ * Callback page component for OIDC authentication redirects.
+ * This page provides a valid route for static export at /auth and /silent-auth,
+ * preventing 404 errors with standards-compliant OAuth 2.0 redirect URIs.
+ *
+ * The @axa-fr/react-oidc library intercepts these routes when OAuth callback
+ * parameters are present and renders its own callback handler. This component
+ * serves as a fallback if somehow rendered directly.
+ */
+export default function CallbackPage() {
+ const router = useRouter();
+
+ useEffect(() => {
+ // Fallback: if this component renders directly, redirect to /peers
+ const timer = setTimeout(() => {
+ router.replace("/peers");
+ }, 100);
+
+ return () => clearTimeout(timer);
+ }, [router]);
+
+ return ;
+}
diff --git a/src/auth/OIDCProvider.tsx b/src/auth/OIDCProvider.tsx
index 69175fbc..0c72574b 100644
--- a/src/auth/OIDCProvider.tsx
+++ b/src/auth/OIDCProvider.tsx
@@ -130,6 +130,26 @@ const CallBackSuccess = () => {
const params = useSearchParams();
const errorParam = params.get("error");
const currentPath = usePathname();
- useRedirect(currentPath, true, !errorParam);
+ const router = useRouter();
+
+ useEffect(() => {
+ if (!errorParam && currentPath === "/auth") {
+ // Redirect to /peers after a brief delay to ensure tokens are stored
+ const timer = setTimeout(() => {
+ let queryParams = "";
+ try {
+ const stored = localStorage.getItem("netbird-query-params");
+ if (stored) {
+ queryParams = `?${stored}`;
+ localStorage.removeItem("netbird-query-params");
+ }
+ } catch (e) { }
+
+ router.replace(`/peers${queryParams}`);
+ }, 100);
+ return () => clearTimeout(timer);
+ }
+ }, [errorParam, currentPath, router]);
+
return ;
};
diff --git a/src/utils/config.ts b/src/utils/config.ts
index c16d9ac1..f67aead7 100644
--- a/src/utils/config.ts
+++ b/src/utils/config.ts
@@ -25,8 +25,8 @@ interface Config {
*/
const loadConfig = (): Config => {
let configJson: any;
- let redirectURI = "/#callback";
- let silentRedirectURI = "/#silent-callback";
+ let redirectURI = "/auth";
+ let silentRedirectURI = "/silent-auth";
let tokenSource = "accessToken";
if (process.env.APP_ENV === "test") {