jdPerez Logo Header
5 minutos de lectura | 09/12/2024

Error 404 con target static y rutas con _slug

Hace poco hice una migración de esta misma web de Gatsby (#ReactJS) a NuxtJS (#VueJS), por supuesto, aquí cambia la lógica de "routing" entre diferentes páginas/controladores de cualquier aplicación.

¿Qué ocurre aquí?, cómo bien sabemos hay mucha diferencia entre VueJS y ReactJS, ReactJS es una librería que permite la construcción de interfaces de usuario a través de componentes usando JSX, mientras que VueJS es una librería de "templates" que se apoya en componentes de JSX, lo cual hace muy diferente el trabajar con el DOM en ambos casos.

En mi caso, para mi web, tengo un hosting sencillo, no puedo utilizar un Server-Side Rendering, si no que en mi creo un Static-Site que me permita mostrar la web.

Cuando renderizamos un Static-Site en ReactJS, esto depende de la librería de routing que usemos, normalmente se hace un pre-loading (como en el routing de Gatsby), entonces podemos permitirnos el utilizar rutas dinámicas que nuestra aplicación sabrá a donde redirigir la url, en NuxtJS no es el caso, NuxtJS necesita saber el destino de la ruta antes de renderizarse.

Esto provoca que en NuxtJS cuando queramos usar las rutas _slug el servidor devuelva un 404 Not Found. Además en mi caso el slug genera un contenido a través de una llamada de GraphQl.

Bien, ¿cómo arreglamos esto?.

Usaremos la función routes de NuxtJS en la sección generate de nuestro nuxt.config.js, ojo con esto por que es muy importante:

En este caso como estamos hablando de una StaticSite solo necesitaremos usar el comando yarn/npm generate, por eso solo haremos esto dentro de la sección generate del nuxt.config.js

Ahora pongamos el caso de que queremos generar de forma dinámica la url de posts, como fue mi caso, para ello dentro de pages tendremos post/_slug.vue, como ejemplo mi fichero tendrá el siguiente contenido:

image-1.png

Si solo tenemos esto y hacemos un generate veremos este resultado:

image-2.png

En un Server-Side, ahora si escribimos {route}/post/example veremos algo como esto:

image-3.png

Pero en un Static-Site esto devolverá un 404. Para arreglarlo debemos irnos al nuxt.config.js y añadir algo como esto:

...
generate: {
	routes: function () {
		return [
			'/post/example'
		]
	}
}
...

Si ahora lanzamos el generate veremos que ha habido un cambio:

image-4.png

Ahora ya, NuxtJS, sabe que hay una ruta con un _slug y que si se escribe esa ruta tiene que mostrar ese componente.

Esto ahora mismo es muy sencillo, ¿no?, si queremos esto lo podemos complicar tanto como queramos, en mi caso yo tengo algo como esto:

...
generate: {
    routes() {
    	return axios({
    		url: 'https://api-graphql.com/api',
    		method: 'post',
    		data: {
    			query: `
    				query ShowPost {
    					posts {
    						slug
    					}
    				}
    			`
    		}
    	}).then((res) => {
    		const posts = res.data.data.posts.map(post => {
    			return {
    				route: '/post/' + post.slug
    			}
    		});
        return posts;
      });
    }
  }
...

De esta forma el generate hara la consulta GraphQl y regresará todas las rutas de los posts para que cuando se escriba esa ruta se pueda renderizar el componente y mostrar el contenido.