Cómo solucionar los errores 404 tras publicar tu web o app
Si tu app funciona en local pero las páginas devuelven 404 tras publicarla, la causa más habitual es la falta de enrutado de aplicación de una sola página (SPA): el servidor busca un archivo llamado /dashboard que no existe, porque esa ruta solo existe en JavaScript. La solución es una regla de fallback que sirva index.html para las rutas de la app. Otras causas son archivos que faltan en la salida de compilación, rutas sensibles a mayúsculas, diferencias con la barra final, una ruta base incorrecta y rutas de API que nunca se desplegaron.
Empieza anotando exactamente qué URL da 404 y cómo llegaste a ella. El patrón apunta directamente a la causa.
Paso 1: identifica el patrón
| Lo que ves | Causa más probable | Ve a |
|---|---|---|
| La página de inicio funciona; los enlaces funcionan; pero al recargar o abrir un enlace directo sale 404 | Falta el fallback SPA | Paso 2 |
| Todas las páginas dan 404, incluida la de inicio | Se publicó la carpeta equivocada, o la compilación no se desplegó | Paso 3 |
| Las páginas cargan, pero las imágenes, fuentes o scripts dan 404 | Archivos que faltan en la compilación, o rutas incorrectas | Paso 4 |
Funciona con /about/, falla con /about (o al revés) | Gestión de la barra final | Paso 5 |
/About falla pero /about funciona | Servidor sensible a mayúsculas | Paso 4 |
La página carga, pero las llamadas de datos a /api/... dan 404 | La API no está desplegada o no tiene ruta | Paso 6 |
| Las URLs antiguas de un sitio anterior dan 404 | Faltan redirecciones | Paso 7 |
| Solo en un dominio personalizado | Configuración de DNS o del dominio | Paso 8 |
Para ver el código de estado real, abre las herramientas de desarrollo (clic derecho → Inspeccionar), ve a la pestaña Red (Network), recarga y mira el estado de la primera petición.
Paso 2: añade el fallback SPA
Este es el caso clásico. En una aplicación de una sola página con React, Vue o Svelte, el servidor solo tiene unos pocos archivos reales: index.html y algunos archivos JavaScript y CSS. Rutas como /dashboard o /projects/42 las gestiona un enrutador en el navegador.
- Hacer clic en un enlace funciona: el enrutador cambia la URL y dibuja la nueva página sin pedir nada al servidor.
- Recargar o abrir un enlace directamente falla: el navegador pide
/dashboardal servidor, el servidor no tiene ese archivo y devuelve 404.
La solución es una regla que diga: si la petición no coincide con un archivo real, sirve index.html con estado 200 y deja que el enrutador tome el control. Cómo añadirla depende del hosting (consulta la documentación actual de tu hosting, porque los detalles cambian):
| Hosting | Regla de fallback habitual |
|---|---|
| Netlify | Un archivo _redirects en la carpeta publicada con /* /index.html 200 |
| Vercel | Una reescritura en vercel.json de todas las rutas a /index.html (los presets de framework suelen gestionarlo) |
| Cloudflare Pages | Sirve un fallback al estilo SPA por defecto cuando no hay un 404.html en la raíz |
| Nginx | try_files $uri $uri/ /index.html; en el bloque location / |
| Apache | Una regla de reescritura en .htaccess que envía las peticiones que no son archivos a index.html |
| GitHub Pages | Sin reescrituras en el servidor; las soluciones habituales son el enrutado por hash o un 404.html que redirige |
Asegúrate de que la regla no se coma los archivos reales: las peticiones a /assets/app.js deben seguir devolviendo el archivo JavaScript. Si devuelven index.html, obtendrás una página en blanco con el error “Failed to load module script”. Consulta cómo solucionar una página en blanco.
Dale también al enrutador una ruta catch-all para que las URLs que no coinciden con ninguna página muestren un amable “Página no encontrada” en lugar de nada.
Si no puedes cambiar la configuración del servidor, el enrutado por hash (URLs como /#/dashboard) evita el problema, porque la parte posterior a # nunca se envía al servidor. Es una solución alternativa, no la primera opción: las URLs son menos bonitas y menos amigables para los buscadores.
Los frameworks que generan las páginas en el servidor o en el momento de compilar (Next.js, Astro y similares) suelen tener archivos reales o rutas de servidor para cada página, así que este problema concreto es menos frecuente allí. Su equivalente es una página que nunca se generó en la compilación.
Paso 3: comprueba qué se desplegó realmente
Si todo da 404, lo más probable es que el servidor no esté sirviendo tu app compilada.
- La carpeta correcta. El hosting debe publicar la salida de compilación (normalmente
distpara Vite,buildpara Create React App,outpara una exportación estática de Next.js), no la raíz del proyecto. - La compilación se ejecutó. Lee el registro del despliegue. Si la compilación falló, el hosting puede no haber desplegado nada, o una versión antigua.
index.htmlestá en el nivel superior de la carpeta publicada, no dentro de una subcarpeta.- La ruta base coincide. Si la app se sirve desde
ejemplo.com/app/, debe compilarse con esa base (labasede Vite, elbasenamede React Router), o todas las rutas y recursos fallarán.
Paso 4: corrige archivos que faltan y rutas incorrectas
Cuando las páginas cargan pero los recursos dan 404:
- Distinción de mayúsculas. macOS y Windows suelen tratar
Logo.pngylogo.pngcomo el mismo archivo. La mayoría de servidores Linux no. Haz que cada referencia coincida exactamente con el nombre real del archivo. - Archivos fuera de la compilación. En Vite, los archivos de
public/se copian tal cual y se referencian desde la raíz (/logo.png). Los archivos importados en el código se empaquetan. Un archivo situado en otro lugar del proyecto puede que ni siquiera se despliegue. - Rutas relativas.
images/photo.jpgse resuelve respecto a la URL actual, así que se rompe en/blog/post-1. Usa/images/photo.jpg. - Archivos subidos guardados en el disco local. Si las subidas de los usuarios se escribieron en la carpeta del propio servidor, desaparecen cuando se despliega una nueva versión. Usa un almacenamiento de archivos adecuado.
Paso 5: gestiona las barras finales de forma coherente
/about y /about/ son URLs distintas. Los hostings difieren en si añaden o quitan la barra, y una discrepancia con tus enlaces o con tu enrutador puede provocar 404 o bucles de redirección. Elige un estilo, haz que tus enlaces lo usen y configura el hosting para redirigir la otra forma hacia él. La coherencia también ayuda a los buscadores, que de otro modo pueden ver dos copias de cada página.
Paso 6: corrige las rutas de API que dan 404
Si la página carga pero la pestaña Red muestra peticiones a /api/... que devuelven 404:
- El backend no está desplegado. Un hosting estático sirve solo archivos; un backend tiene que ejecutarse en algún sitio.
- La ruta se enruta de forma distinta en producción. En desarrollo, un proxy pudo reenviar
/apia un servidor independiente. En producción, el hosting necesita una reescritura equivalente, o el front end debe llamar a la dirección real de la API. - El fallback SPA la capturó. Una petición a la API que devuelve
index.htmlcon estado 200 indica que la regla de fallback es demasiado amplia. Excluye/api/*de ella.
Las peticiones de la app publicada a /api/orders devuelven 404, pero funcionan en la vista previa. Comprueba cómo se enruta /api en la vista previa frente a la app publicada, y haz que el front end publicado llegue al backend de la misma forma.
Paso 7: redirige las URLs antiguas
Si te has cambiado desde otro sitio o has reestructurado el tuyo, las URLs antiguas que aún usan las personas y los buscadores darán 404. Añade una redirección 301 (permanente) desde cada URL antigua a su nuevo destino. Lleva una lista y prueba una muestra después del lanzamiento. Nuestra guía sobre cómo migrar un sitio de WordPress explica cómo crear esa lista.
Paso 8: comprueba el dominio
Si la app funciona en la dirección del hosting pero da 404 en tu dominio personalizado, es posible que el dominio apunte al proyecto equivocado, o que el hosting aún no tenga el dominio asociado a tu sitio. Revisa los registros de DNS y la configuración de dominios del hosting. Consulta cómo conectar un dominio personalizado.
Haz útil tu página 404 real
Algunos 404 son correctos: alguien escribió mal una URL. Haz que esa página sea útil:
- Un mensaje breve y un enlace a la página de inicio y a las secciones clave
- Un cuadro de búsqueda, si el sitio tiene buscador
- La misma cabecera y navegación que el resto del sitio
Si tu configuración lo permite, devuelve un estado 404 real para las páginas que no existen. Un mensaje de “no encontrado” devuelto con estado 200 es lo que los buscadores llaman soft 404, y puede desperdiciar su tiempo de rastreo y confundir la indexación.
Errores comunes
- Probar solo haciendo clic. Prueba siempre pegando URLs profundas en una pestaña nueva y recargando.
- Un fallback que lo captura todo. Los recursos y las rutas de API devuelven
index.html, lo que causa páginas en blanco y errores de API confusos. - Mayúsculas inconsistentes que solo fallan en el servidor.
- Desplegar la carpeta de código fuente en lugar de la salida de compilación.
- Reestructurar URLs sin redirecciones. Cada enlace antiguo se convierte en un 404.
Los 404 en Mythex
En Mythex publicas desde el espacio de trabajo, y los front ends estáticos se despliegan como sitios estáticos. Si una página publicada da 404, indica al agente la URL exacta, si ocurre al recargar o al hacer clic, y lo que muestra la pestaña Red, y pídele que revise el enrutado. Vuelve a publicar tras la corrección, porque la app en vivo es una instantánea hasta que vuelvas a publicarla. Si cambiaste el proyecto hace poco y el sitio en vivo parece antiguo, vuelve a publicar y recarga forzando la caché. Usa Arreglar con IA en el diálogo de publicación si la compilación falla. Consulta Cómo publicar y Solución de problemas de publicación en la documentación, y nuestra guía sobre cómo depurar una app creada con IA.
Lista de comprobación de 404
- Anotaste exactamente qué URLs dan 404 y si ocurre al hacer clic, al recargar o en ambos casos
- El fallback SPA sirve
index.htmlpara las rutas de la app, con estado 200 - El fallback excluye los archivos reales y
/api/* - El enrutador tiene una ruta catch-all de “no encontrado”
- La carpeta de salida de compilación es la que se publica, y la compilación tuvo éxito
- La ruta base coincide con el lugar donde se sirve la app
- Las mayúsculas del nombre de cada archivo coinciden con cada referencia
- Las rutas de los recursos empiezan por
/ - El estilo de barra final es coherente
- Las rutas de API están desplegadas y enrutadas en producción
- Redirecciones 301 para las URLs antiguas
- Las URLs profundas se probaron pegándolas en una pestaña nueva
Preguntas
¿Por qué recibo un 404 al recargar una página en mi app de React?
En una app de una sola página, rutas como /dashboard existen solo en JavaScript. Hacer clic en un enlace funciona porque el enrutador lo gestiona en el navegador, pero al recargar se pide al servidor un archivo /dashboard que no existe. La solución es una regla de fallback que sirva index.html para las rutas de la app.
¿Cómo añado un fallback SPA en Netlify, Vercel o Nginx?
En Netlify, añade un archivo _redirects con /* /index.html 200. En Vercel, añade una reescritura en vercel.json que envíe todas las rutas a /index.html. En Nginx, usa try_files $uri $uri/ /index.html; dentro del bloque location. Consulta la documentación de tu hosting, porque las reglas cambian.
¿Por qué mis imágenes o archivos dan 404 tras publicar?
Normalmente el archivo no está en la salida de compilación, la mayúscula de la ruta no coincide (los servidores suelen distinguir mayúsculas y minúsculas, a diferencia de tu portátil), o la ruta es relativa cuando debería empezar por una barra.
¿Una página que no existe debe devolver un estado 404 real?
Sí. Muestra una página de no encontrado útil, pero con estado 404 cuando tu configuración lo permita. Los buscadores tratan un mensaje de “no encontrado” devuelto con estado 200 como un soft 404, lo que desperdicia tiempo de rastreo y puede confundir la indexación.