Inicio / Blog / Como solucionar problema de react router dom en producción

Erik Mclean

Como solucionar problema de react router dom en producción

7 min read

Si estas aquí, seguramente, es porque acabas de subir tu aplicación de react junto a react-router-dom, y descubriste que al refrescar la página, siendo esta distinta de la ruta principal, se te rompe la aplicación y devuelve un error 404.

Por eso en este artículo voy a explicarte la razón de este problema y dos formas de solucionarlo.

Indice


Porque ocurre este problema?

Para comprender este problema, primero debemos entender como funciona un servidor web.

Yo no cuento con conocimientos avanzados en este tema, pero es muy importante conocer sobre esto, ya que nos ayudara a la hora de tener en cuenta sobre donde y como hacer el deploy de la aplicación que se está desarrollando.

Cuando se accede a un sitio web en su ruta principal, osea https://domain.com, el servidor buscara el archivo index.html para servirlo en la página. Si se quiere extender la url para acceder a la sección sobre mi, haríamos lo siguiente:

https://domain.com/sobremi

Esto es lo que hay que comprender.
Cuando indicamos esto, el servidor, si nadie le indica que debe hacer con esa url, va a buscar el archivo sobremi.html, el cual no existe. Y es por eso que al refrescar la página, el servidor devolverá un error 404.

⬆ Volver a índice


Porque al redireccionar con un componente Link no ocurre un error?

Cuando se usa el componente Link, que proporciona react-router-dom, para redireccionar a la página /sobremi funciona correctamente.
Esto es porque, cuando usamos Link, en vez de la etiqueta ``, se trabaja directamente sobre el cliente, no se solicita ningún dato al servidor, por lo que este no interferirá en las operaciones que se realicen.

Esto react-router-dom lo hace para optimizar la carga del sitio mediante procesos de su estructura interna. Esto nos beneficia cuando el usuario interactúa con la página desde la ruta principal, pero cuando refresque el navegador, estando en una ruta distinta a la principal, se romperá el sitio, ya que ahí si va a interferir el servidor.

⬆ Volver a índice


Como se soluciona?

La solución a este problema es más fácil de lo que parece. Lo que se debe hacer es indicarle al servidor lo que tiene que hacer, cuando ingresamos en una ruta distinta a la principal.

En vez de que, al entrar en /sobremi, busque el archivo sobremi.html, se debe indicar que, independientemente de la ruta que sea, siempre se sirva al archivo index.html.

Para hacer esto tenemos dos formas:

⬆ Volver a índice


Solución con Nodejs

La primera solución es la de crear nuestro propio servidor con Nodejs, utilizando Express.
Si no tienes conocimientos sobre Nodejs no te preocupes, voy a dejar toda la información posible para que puedas configurar tu propio servidor. Sino también tienes la otra forma de hacerlo, que no requiere crear un servidor, solo basta con configurar Netlify.

Voy a explicar desde 0 como crear el servidor, por lo que si ya sabes estos pasos los puedes saltear e ir a la configuración de las rutas.
Debes tener intalado Nodejs en tu sistema operativo para continuar.

Crear servidor

Lo primero que vamos a hacer es iniciar un proyecto de Nodejs.
Para eso vamos a la terminal y nos ubicamos en la carpeta que deseamos crear el proyecto. Luego escribimos el siguiente comando:

npm init -y

Luego procedemos a instalar express para configurar nuestro proyecto:

npm i express

Una vez que tenemos todo instalado vamos a configurar nuestro archivo package.json. Yo se los voy a servir listo para copiar y pegar, aunque pueden configurarlo según sus gustos.

{
    "name": "routes",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "type": "module",
    "scripts": {
        "start": "node index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "ISC",
    "dependencies": {
        "express": "^4.18.2"
    }
}

Configurar rutas

Con todo esto ya podemos comenzar a configurar el servidor. Antes de hacer esto, primero debes tener tu proyecto de react terminado y debe tener hecha la build (Ejecutar el comando npm run build).
Si el proyecto está hecho con ViteJs, tendrás una carpeta dist. Lo que debes hacer con esa carpeta es copiarla en la carpeta del proyecto de NodeJs, para así poder utilizarla.

Te debería quedar una estructura del proyecto así:

| - node_modules
| - dist
| - index.js
| - package.json
| - package-lock.json

Ahora debemos configurar el archivo index.js, el cual debes crear tú (No lo había comentado antes).

//---- Dependencies
    import express from "express";
    import path from "path";
    import * as url from 'url';

// Initialize express
    const app = express();
    const __dirname =  url.fileURLToPath(new URL('.', import.meta.url));

// Settings
    app.set("port", process.env.PORT || 3000);
    app.use(express.static(path.join(__dirname,'dist')));

// Routes
    app.get("/*", (req, res) => {
        res.sendFile(path.join(__dirname, "dist/index.html"));
    });

// Listening the Server
    app.listen(app.get("port"), ()=>{
        console.log("Server on port", app.get("port"));
    });

En vez de usar, app.get('/*'), pueden marcar de forma manual solo las rutas que quieran, y dejar otras sin marcar, con el fin de manejar los errores.

Por ejemplo, suponiendo que se tienen 4 rutas:

Si quieren que al refrescar la página en la ruta /dashboard no se quede guardada, pueden hacer esto

// Routes
    app.get("/", (req, res) => {
        res.sendFile(path.join(__dirname, "dist/index.html"));
    });

    app.get("/sobremi", (req, res) => {
        res.sendFile(path.join(__dirname, "dist/index.html"));
    });

    app.get("/articulos", (req, res) => {
        res.sendFile(path.join(__dirname, "dist/index.html"));
    });

No se indica nada sobre la ruta /dashboard, por lo que el servidor devolvera un error

Deploy

Lo que debes hacer a continuación es subir el servidor a un hosting que acepte a NodeJs. Hay muchas opciones, entre las gratuitas están:

Algo muy importante que se debe hacer antes de subir el servidor es deshabilitar la carpeta node_modules para subir al repositorio. Eso lo hacemos creando un archivo llamado .gitignore. Dentro de este archivo solo debemos indicar la ruta de la carpeta que queremos ignorar:

node_modules

Con eso ya ignoramos la carpeta node_modules para subir a nuestro repositorio.

Para hacer el deploy de nuestro servidor nodejs no es muy complicado. Puedes ver un video de 5 minutos para ver como hacer el deploy. El servidor está configurado para subirse sin problemas.

⬆ Volver a índice


Solución con Netlify

Esta solución la lei en un articulo que encontré en internet. Si quieres mirarlo puede hacerlo dando click aqui.

Esta forma es tan fácil como crear un archivo llamado netlify.toml con el siguiente contendió dentro:

[build]
    command = "npm run build"
    publish = "/build"
    base = "/"

[[redirects]]
    from = "/*"
    to = "/index.html"
    status = 200

Esto se encargara de avisarle al servidor que, cada vez que se acceda a una ruta, sin importar cual sea, siempre va a pasar por el index.html.

Como verán, esta forma es muy sencilla, aunque tiene sus limitaciones.
Si no tienen un proyecto tan grande, pueden utilizar esta solución sin problemas. Pero como dije, todo depende de los requerimientos del proyecto.

⬆ Volver a índice


Muchas gracias por leer el artículos. 😁Un saludo!!

24 de abril de 2023