• Sobre mí
  • Proyectos
  • Contacto
  • Blog

Apasionado por el desarrollo web y el diseño de interfaces intuitivas.

Cada error es un paso. Cada línea, un aprendizaje.

📍   Salou, Tarragona, España ✉️   frankuxui.dev@gmail.com 📞   +34 641932611

Curriculum

Ver mi curriculum completo

Mapa del sitio

  • Inicio
  • Blog
  • Proyectos
  • Sobre mi
  • Mi misión
  • Sitemap

Contácto

  • Página de contácto
  • LinkedIn
  • GitHub

2026 Frankuxui - Todos los derechos reservados

  • Términos y condiciones
  • Política de privacidad
  • Política de cookies
Imagen de Unsplash creada por Kjell-Jostein Sivertsen
Imagen de Unsplash creada por Kjell-Jostein Sivertsen
  • React
  • React Router
  • JavaScript

Articulo publicado el 27 de junio de 2026

Por Frank Esteban Isdray Junco

Cómo crear una app con React y React Router desde cero

Guía práctica para iniciar un proyecto con Vite, configurar rutas, layouts, páginas dinámicas y una pantalla 404

Crear una aplicación con React es bastante directo, pero en cuanto el proyecto necesita varias páginas aparece una pregunta importante: ¿cómo navegamos entre ellas sin recargar completamente el navegador?

React se encarga de construir la interfaz. React Router añade el sistema de rutas que conecta una URL con una pantalla concreta y permite navegar dentro de una SPA, o Single Page Application.

En esta guía vamos a crear una aplicación desde cero con:

  • React y Vite
  • React Router en modo declarativo
  • un layout compartido
  • varias páginas
  • navegación con enlaces activos
  • una ruta dinámica
  • una página para rutas no encontradas

Requisitos previos

Antes de empezar necesitas tener instalados:

  • Node.js en una versión con soporte activo
  • npm, pnpm o yarn
  • un editor como Visual Studio Code

Puedes comprobar Node.js y npm desde la terminal:

bash
node --version
npm --version

1. Crear el proyecto React con Vite

Vite proporciona un entorno de desarrollo rápido y una configuración inicial pequeña. Ejecuta:

bash
npm create vite@latest mi-app-react -- --template react

Entra en la carpeta e instala las dependencias:

bash
cd mi-app-react
npm install

Inicia el servidor de desarrollo:

bash
npm run dev

Vite mostrará en la terminal la URL local de la aplicación, normalmente http://localhost:5173.

2. Instalar React Router

Instala React Router dentro del proyecto:

bash
npm install react-router

En este ejemplo usaremos el modo declarativo. Es una buena opción para aprender el sistema de rutas y para aplicaciones que no necesitan loaders o actions asociados a cada ruta.

3. Estructura recomendada

Vamos a separar las páginas, el layout y la configuración principal:

txt
src/
├── layouts/
│   └── RootLayout.jsx
├── pages/
│   ├── HomePage.jsx
│   ├── AboutPage.jsx
│   ├── ProjectPage.jsx
│   └── NotFoundPage.jsx
├── App.jsx
├── main.jsx
└── index.css

No es una estructura obligatoria, pero evita que App.jsx termine conteniendo toda la interfaz del proyecto.

4. Envolver la aplicación con BrowserRouter

Abre src/main.jsx y añade BrowserRouter alrededor de la aplicación:

jsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router";
import App from "./App.jsx";
import "./index.css";

createRoot(document.getElementById("root")).render(
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>
);

BrowserRouter mantiene sincronizada la interfaz con la URL utilizando la API History del navegador.

Solo debe existir un router principal envolviendo esta parte de la aplicación. No es necesario añadir otro BrowserRouter dentro de cada página.

5. Crear las páginas

Empezamos con una página de inicio:

jsx
// src/pages/HomePage.jsx
export default function HomePage() {
  return (
    <section>
      <h1>Inicio</h1>
      <p>Esta es la página principal de la aplicación.</p>
    </section>
  );
}

Creamos también la página sobre el proyecto:

jsx
// src/pages/AboutPage.jsx
export default function AboutPage() {
  return (
    <section>
      <h1>Sobre nosotros</h1>
      <p>Esta aplicación utiliza React y React Router.</p>
    </section>
  );
}

Y una página para las URLs que no existen:

jsx
// src/pages/NotFoundPage.jsx
import { Link } from "react-router";

export default function NotFoundPage() {
  return (
    <section>
      <h1>Página no encontrada</h1>
      <p>La dirección solicitada no existe.</p>
      <Link to="/">Volver al inicio</Link>
    </section>
  );
}

6. Crear un layout compartido

Un layout permite reutilizar la cabecera, la navegación y el pie de página entre diferentes rutas.

jsx
// src/layouts/RootLayout.jsx
import { NavLink, Outlet } from "react-router";

export default function RootLayout() {
  return (
    <div className="app-shell">
      <header>
        <a href="#main-content" className="skip-link">
          Saltar al contenido
        </a>

        <nav aria-label="Navegación principal">
          <NavLink to="/" end>
            Inicio
          </NavLink>
          <NavLink to="/sobre-nosotros">Sobre nosotros</NavLink>
        </nav>
      </header>

      <main id="main-content">
        <Outlet />
      </main>

      <footer>Mi aplicación React</footer>
    </div>
  );
}

Outlet indica el lugar exacto donde React Router debe renderizar la ruta hija activa.

Usamos NavLink en la navegación porque permite identificar el enlace activo. Para enlaces internos no conviene utilizar un <a href> convencional, ya que provocaría una nueva carga del documento.

7. Configurar las rutas

Ahora conectamos cada URL con su página desde src/App.jsx:

jsx
import { Route, Routes } from "react-router";
import RootLayout from "./layouts/RootLayout.jsx";
import AboutPage from "./pages/AboutPage.jsx";
import HomePage from "./pages/HomePage.jsx";
import NotFoundPage from "./pages/NotFoundPage.jsx";
import ProjectPage from "./pages/ProjectPage.jsx";

export default function App() {
  return (
    <Routes>
      <Route element={<RootLayout />}>
        <Route index element={<HomePage />} />
        <Route path="sobre-nosotros" element={<AboutPage />} />
        <Route path="proyectos/:projectId" element={<ProjectPage />} />
        <Route path="*" element={<NotFoundPage />} />
      </Route>
    </Routes>
  );
}

La ruta con index se muestra cuando coincide la ruta padre, en este caso /.

La ruta * captura cualquier URL que no haya coincidido antes y muestra la página 404.

8. Crear una ruta dinámica

Las rutas dinámicas permiten representar distintos recursos con una misma página. En /proyectos/:projectId, el segmento projectId cambia según el proyecto solicitado.

jsx
// src/pages/ProjectPage.jsx
import { Link, useParams } from "react-router";

export default function ProjectPage() {
  const { projectId } = useParams();

  return (
    <section>
      <h1>Proyecto {projectId}</h1>
      <p>Estás viendo el detalle del proyecto con ID {projectId}.</p>
      <Link to="/">Volver al inicio</Link>
    </section>
  );
}

Si visitas /proyectos/portfolio, useParams() devolverá:

js
{
  projectId: "portfolio";
}

Los parámetros llegan como cadenas de texto. Si representan un número, debes validarlos y convertirlos antes de usarlos.

9. Estilos para los enlaces activos

NavLink puede generar una clase en función de si la ruta está activa:

jsx
<NavLink to="/sobre-nosotros" className={({ isActive }) => (isActive ? "nav-link active" : "nav-link")}>
  Sobre nosotros
</NavLink>

Después puedes definir los estilos en src/index.css:

css
.nav-link {
  color: #555;
  text-decoration: none;
}

.nav-link:hover {
  color: #111;
}

.nav-link.active {
  color: #111;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 0.3rem;
}

No dependas únicamente del color para comunicar qué ruta está activa. El peso o el subrayado ayudan a que el estado sea más evidente.

10. Navegar desde una acción

Para la navegación visible utiliza Link o NavLink. Cuando la navegación depende de una acción, como completar correctamente un formulario, puedes usar useNavigate.

jsx
import { useNavigate } from "react-router";

export default function LoginForm() {
  const navigate = useNavigate();

  function handleSubmit(event) {
    event.preventDefault();

    const loginWasSuccessful = true;

    if (loginWasSuccessful) {
      navigate("/perfil");
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Iniciar sesión</button>
    </form>
  );
}

No uses useNavigate para reemplazar enlaces normales. Un enlace conserva mejor la semántica, la accesibilidad y las funciones habituales del navegador.

11. Ejecutar y compilar la aplicación

Durante el desarrollo:

bash
npm run dev

Para crear la versión de producción:

bash
npm run build

Vite generará los archivos optimizados dentro de dist/.

Puedes comprobar esa compilación localmente con:

bash
npm run preview

12. Configurar el servidor para producción

BrowserRouter utiliza URLs reales como /sobre-nosotros o /proyectos/portfolio.

Si alguien abre directamente una de esas URLs, el servidor debe devolver index.html para que React Router resuelva la ruta en el navegador. Sin esa regla de fallback, es habitual que la portada funcione y que las rutas internas devuelvan un error 404 al recargar.

Servicios como Vercel, Netlify, Cloudflare Pages, Nginx o Apache permiten configurar este comportamiento, aunque la sintaxis cambia según la plataforma.

Buenas prácticas

  • Mantén las páginas separadas de los componentes reutilizables.
  • Usa un layout con Outlet para la estructura compartida.
  • Utiliza Link y NavLink para navegación interna.
  • Reserva useNavigate para navegaciones provocadas por acciones.
  • Añade siempre una ruta * para controlar las páginas no encontradas.
  • Valida los parámetros recibidos con useParams.
  • Comprueba que las rutas internas funcionan después del despliegue.
  • Divide páginas grandes con lazy cuando el proyecto empiece a crecer.

Resultado final

Con esta configuración ya tienes una base clara para construir una aplicación React con varias páginas sin recargas completas.

React se ocupa de la interfaz, React Router relaciona cada URL con su pantalla y el layout evita repetir la estructura general. A partir de aquí puedes añadir autenticación, rutas protegidas, carga de datos y división de código según las necesidades del proyecto.

En este artículo

  1. Requisitos previos
  2. 1. Crear el proyecto React con Vite
  3. 2. Instalar React Router
  4. 3. Estructura recomendada
  5. 4. Envolver la aplicación con BrowserRouter
  6. 5. Crear las páginas
  7. 6. Crear un layout compartido
  8. 7. Configurar las rutas
  9. 8. Crear una ruta dinámica
  10. 9. Estilos para los enlaces activos
  11. 10. Navegar desde una acción
  12. 11. Ejecutar y compilar la aplicación
  13. 12. Configurar el servidor para producción
  14. Buenas prácticas
  15. Resultado final

Articulos relacionados

Estos articulos pueden interesarte si te gusto este articulo.

Fotografía de Unsplash creada por Carter Obasohan
Imagen del articulo Tooltip reutilizable creado con JavaScript Vanilla
27 de junio de 2026
HTML
·JavaScript

Creando un Tooltip reutilizable con JavaScript Vanilla

Aprende a construir un sistema de tooltips flexible, accesible y controlable sin depender de librerías externas.

Fotografía de Unsplash creada por Natalia Rudomin
Imagen del articulo Tabs accesibles y escalables en JavaScript Vanilla
27 de junio de 2026
JavaScript
·Componentes
·Accesibilidad

Tabs reutilizables con JavaScript Vanilla

Un componente accesible, reutilizable y escalable con API programatica, teclado, ARIA y registro interno

Fotografía de Unsplash creada por Michael Busch
Imagen del articulo Configurando Shiki Syntax Highlighter en Next.js con MDX
27 de junio de 2026
Next.js
·React
·Shiki
·MDX
·SSR

Configurando Shiki Syntax Highlighter

Configurando y creando un componente para resaltar la sintaxis de código en un blog utilizando Shiki y Next.js con server-side rendering.