Aplicación Vue con Vue-router en subcarpeta

«Una vez visto, todo el mundo es listo»

Eso es lo que he pensado cuando he dado con la tecla. Parece sencillo y hay documentación, pero me ha costado dar con la solución. He trabajado en el pasado con Vue 2.0, 3.0 con webpack y ahora con VueJS 3.2 con Vite. Las cosas… cambian un poco.

Si quieres instalar tu aplicación de VueJS con Vue-router en un subdirectorio, habrás sufrido los problemas de rutas absolutas. Has intentado configurar rutas relativas y seguramente te habrás encontrado con problemas al recargar pantalla o hacer F5, que la app ya no carga y te da un error 404.

En este artículo, explico los tres puntos que has de tener en cuenta. Es mucho más sencillo de lo que te imaginas.

Configura tu aplicación VueJS 3.2 con Vite y Vue-router para que funcione con rutas relativas

Supongamos que nuestra aplicación se instala en https://midominio.com/app. Fíjate que la hemos instalado sobre la carpeta app y no utilizamos la raíz del dominio.

Supongamos también que trabajamos con Vue 3.2 y Vite y que nuestro servidor web es Apache. En definitiva, vamos a tener que hacer tres cosas:

  1. Tocar el fichero de configuración Vite
  2. Configurar correctamente vue-router
  3. Colocar un .htaccess que utiliza el módulo mod_rewrite que deberías activar en Apache

Vamos a por ello:

Configura Vite para que trabaje en un subdirectorio

Localizamos el fichero vite.config.js que estará en la raíz de nuestro proyecto. Hemos de añadir dos atributos a la configuración. Un resumen es el siguiente:

export default defineConfig({
    // configura las rutas relativas al hacer npm run build
    base: '/app',
    publicPath: '/app',
})

Este fragmento de código hace que todas las rutas de recursos incorporen como base de la URL el recurso /app.

Pero cada vez que cliquemos en un enlace de vue-router, nos cambiará la URL y nos llevará a la raíz. La aplicación funcionará, porque la redirección es meramente estética, pero si recargas la pantalla, no cargará el recurso raíz de la aplicación.

Configura Vue-router para que añada la subcarpeta a las rutas

El siguiente fragmento, tendremos que configurarlo en el index.js de nuestro vue-router. Habitualmente, lo encontrarás en src/router/index.js.

Esta configuración, hace que al clicar en cualquiera de nuestras routes incluyan por delante el recurso /app.

const router = createRouter({
  history: createWebHistory('/app'),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
    ...
  ]
})

Fíjate que incorporamos por parámetro a createWebHistory la ruta sobre la que queremos que funcione nuestra aplicación.

Ahora, verás que todo tiene sentido, que tu aplicación respeta las rutas que tenías en mente. Pero hay un problema: cuando recargas la pantalla, Apache no localiza la ruta y te devuelve un bonito error 404.

Nos falta el último paso.

Configura .htaccess de Apache

Para que Apache localice el recurso de la raíz de nuestra app (index.html), tendremos que añadir un .htaccess en la raíz de nuestra aplicación.

Para incluir un .htaccess en la raíz de la aplicación y que cuando compilemos la aplicación, la copie en dist/, tendremos que añadir éste fichero en la carpeta public/.

Por tanto, añadimos dentro de public/ un fichero .htaccess con el siguiente contenido:

Options -MultiViews

RewriteEngine On
RewriteBase /app
RewriteRule ^app/index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /app/index.html [L]

Finalmente y para terminar, compilamos y construimos la aplicación con el siguiente comando:

npm run build

Referencias:

Ibai

Apasionado por la tecnología, el software, las interfaces de usuario (UX UI) y los sistemas. Utilizo este canal de comunicación para transmitir de manera informal, y muchas veces "rápido", pequeñas aportaciones a la comunidad software.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *


El periodo de verificación de reCAPTCHA ha caducado. Por favor, recarga la página.

*

Artículos relacionados