RouterProvider (MichiProvider)
Es el Proveedor principal del enrutador. Por motivos felinos, se recomienda importar este componente como:
import { RouterProvider as MichiProvider } from '@arielgonzaguer/michi-router';.
Toma dos props y un children:
- routes:
Array<{ path: string; component: React.ReactNode; }>→ Array de rutas disponibles - layout:
React.ComponentType→ Componente de layout opcional para envolver todas las rutas - children:
React.ReactNode→ Contenido a mostrar cuando no hay coincidencia de ruta (404)
const getCurrentPath = () => { return window.location.pathname;};
export function RouterProvider({ routes, children, layout: Layout,}: RouterProviderProps) { const [path, setPath] = useState(getCurrentPath());
useEffect(() => {
const handlePopState = () => setPath(window.location.pathname); window.addEventListener("popstate", handlePopState); return () => window.removeEventListener("popstate", handlePopState); }, []);
const navigate = useCallback((to: string) => { if (!isBrowser) { setPath(to); return; }
// Validación básica de la URL para prevenir navegación a URLs maliciosas if ( typeof to !== "string" || to.includes("javascript:") || to.includes("data:") ) { console.warn("MichiRouter: URL potencialmente insegura bloqueada:", to); return; }
window.history.pushState({}, "", to); setPath(to); }, []);
// Encontrar la ruta actual const currentRoute = routes.find((route) => route.path === path); const routeContent = currentRoute ? currentRoute.component : children;
try { return ( <RouterContext.Provider value={{ path, navigate }}> {Layout ? <Layout>{routeContent}</Layout> : routeContent} </RouterContext.Provider> ); } catch (error) { console.error("Error en RouterProvider:", error); return ( <div>Error en el enrutador. Consulta la consola para más detalles.</div> ); }}Ejemplo de uso:
// enrutadoimport { RouterProvider as MichiProvider, Protected,} from "@arielgonzaguer/michi-router";
// componentes / páginasimport Landing from "../pages/Landing";import LoginPage from "../pages/LoginPage";import ResetContraseña from "./ResetContraseña";
import Home from "../pages/Home";import NotFound404 from "../components/NotFound404";
import ActualizarKegs from "../pages/ActualizarKegs";import VerKegInfoScan from "./VerKegInfoScan";
import Configuracion from "../pages/Configuracion";
// layoutimport BaseLayout from "../layouts/BaseLayout";
// store que maneja autenticación → para Protectedimport useAuthStore from "../store/useAuthStore";
// componente de enrutadoexport function MichiRouter() { // objeto de configuración para Protected const configObject = { states: useAuthStore(), redirectionPath: "/", loadingComponent: ( <div className="w-full h-screen flex items-center justify-center"> Cargando... </div> ), defaultMessage: false, };
const rutas = [ { path: "/", component: <Landing /> }, { path: "/login", component: <LoginPage /> }, { path: "/reset-password", component: <ResetContraseña /> }, { path: "/home", component: ( <Protected configObject={configObject}> <Home /> </Protected> ), }, { path: "/actualizar-kegs", component: ( <Protected configObject={configObject}> <ActualizarKegs /> </Protected> ), }, { path: "/ver-kegs-scan", component: ( <Protected configObject={configObject}> <VerKegInfoScan /> </Protected> ), }, { path: "/configuracion", component: ( <Protected configObject={configObject}> <Configuracion /> </Protected> ), }, ]; return ( <RouterProvider routes={rutas} layout={BaseLayout}> <NotFound404 /> </RouterProvider> );}// componente raíz de la app// este componente suele ser App.tsximport MichiRouter from "./componentes/MichiRouter";
export default function App() { return <MichiRouter />;}Características de Seguridad
Sección titulada «Características de Seguridad»RouterProvider incluye varias medidas de seguridad integradas:
Protección contra URLs Maliciosas
Sección titulada «Protección contra URLs Maliciosas»El router bloquea automáticamente URLs potencialmente peligrosas:
// ❌ Estas URLs son bloqueadas automáticamentenavigate('javascript:alert("XSS")');navigate('data:text/html,<script>alert("XSS")</script>');
// ✅ Estas URLs son permitidasnavigate("/dashboard");navigate("/user/123");navigate("https://external-site.com");🔔
Las rutas para
MichiProvidery objeto de configuración paraProtectedusan hooks, por lo que deben estar dentro de un componente React.