Redirect app root to login when visiting /generadorexamenesllm without a session.

This fixes the blank page on the base URL by normalizing the no-trailing-slash path in nginx and redirecting unauthenticated users to /login before React mounts.
This commit is contained in:
Mireya Cueto Garrido
2026-06-03 12:45:24 +02:00
parent d06b961a73
commit 182eae1e36
5 changed files with 52 additions and 2 deletions
+5
View File
@@ -50,6 +50,11 @@ server {
try_files $uri =404; try_files $uri =404;
} }
# Raíz sin barra final → login (evita pantalla en blanco por basename)
location = /generadorexamenesllm {
return 301 /generadorexamenesllm/login;
}
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
+2 -2
View File
@@ -1,9 +1,9 @@
import { Navigate, Route, Routes } from "react-router-dom"; import { Navigate, Route, Routes } from "react-router-dom";
import Layout from "./components/layout/Layout"; import Layout from "./components/layout/Layout";
import ProtectedRoute from "./components/layout/ProtectedRoute"; import ProtectedRoute from "./components/layout/ProtectedRoute";
import RootRoute from "./components/layout/RootRoute";
import LoginPage from "./pages/LoginPage"; import LoginPage from "./pages/LoginPage";
import RegisterPage from "./pages/RegisterPage"; import RegisterPage from "./pages/RegisterPage";
import DashboardPage from "./pages/DashboardPage";
import CreateTemplatePage from "./pages/CreateTemplatePage"; import CreateTemplatePage from "./pages/CreateTemplatePage";
import TemplateDetailPage from "./pages/TemplateDetailPage"; import TemplateDetailPage from "./pages/TemplateDetailPage";
import NotFoundPage from "./pages/NotFoundPage"; import NotFoundPage from "./pages/NotFoundPage";
@@ -21,7 +21,7 @@ export default function App() {
</ProtectedRoute> </ProtectedRoute>
} }
> >
<Route path="/" element={<DashboardPage />} /> <Route path="/" element={<RootRoute />} />
<Route path="/plantillas/nueva" element={<CreateTemplatePage />} /> <Route path="/plantillas/nueva" element={<CreateTemplatePage />} />
<Route path="/plantillas/:templateId" element={<TemplateDetailPage />} /> <Route path="/plantillas/:templateId" element={<TemplateDetailPage />} />
</Route> </Route>
@@ -0,0 +1,17 @@
import { Navigate } from "react-router-dom";
import { useAuth } from "../../context/AuthContext";
import { SpinnerCenter } from "../ui/Spinner";
import DashboardPage from "../../pages/DashboardPage";
/** Raíz de la app: login si no hay sesión, dashboard si la hay. */
export default function RootRoute() {
const { isAuthenticated, loading } = useAuth();
if (loading) return <SpinnerCenter label="Cargando tu sesión…" />;
if (!isAuthenticated) {
return <Navigate to="/login" replace />;
}
return <DashboardPage />;
}
+3
View File
@@ -4,8 +4,11 @@ import { BrowserRouter } from "react-router-dom";
import App from "./App"; import App from "./App";
import { AuthProvider } from "./context/AuthContext"; import { AuthProvider } from "./context/AuthContext";
import { ToastProvider } from "./context/ToastContext"; import { ToastProvider } from "./context/ToastContext";
import { redirectRootToLoginIfNeeded } from "./utils/redirectRoot";
import "./index.css"; import "./index.css";
redirectRootToLoginIfNeeded();
ReactDOM.createRoot(document.getElementById("root")).render( ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode> <React.StrictMode>
<BrowserRouter basename={import.meta.env.BASE_URL}> <BrowserRouter basename={import.meta.env.BASE_URL}>
+25
View File
@@ -0,0 +1,25 @@
const TOKEN_KEY = "genex_token";
/**
* Si el usuario entra en la raíz de la app sin sesión, redirige a /login
* antes de montar React (evita pantalla en blanco por basename sin barra final).
*/
export function redirectRootToLoginIfNeeded() {
const base = import.meta.env.BASE_URL || "/";
const baseNoSlash = base.replace(/\/$/, "");
const { pathname, search, hash } = window.location;
const normalizedPath = pathname.replace(/\/$/, "") || "/";
const isAppRoot =
normalizedPath === baseNoSlash ||
normalizedPath === "/" ||
pathname === base;
if (!isAppRoot) return;
if (localStorage.getItem(TOKEN_KEY)) return;
const loginUrl = `${baseNoSlash}/login${search}${hash}`;
if (pathname + search + hash !== `${baseNoSlash}/login${search}${hash}`) {
window.location.replace(loginUrl);
}
}