Home > Software design >  Vue-router: No route works after build
Vue-router: No route works after build

Time:09-29

I created a project with Vite, Pinia and Vue-router. Everything works perfectly in development, but when I access the build, only the main path works. All other redirects return 404:

"Failed to load resource: the server responded with a status of 404 ()" "crbug/1173575, non-JS module files deprecated. (anonymous) @ VM10:6789"

Any idea what could be happening?

*** Main.js ***

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'

// Font Awesome
import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'
import { fab } from '@fortawesome/free-brands-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

//Router
import router from './router'

//Pinia
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

library.add(fas, far, fab);

const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);

createApp(App)
.use(pinia)
.use(router)
.component('fa', FontAwesomeIcon)
.mount('#app')

*** App.vue ***

 <script setup>
import { RouterView } from "vue-router";


</script>

<template>
  <RouterView />
</template>

*** router/index.js ***

    import { createRouter, createWebHistory } from 'vue-router'

import { useAuthStore } from '../stores/AuthStore';

const router = createRouter({
    history: createWebHistory(),
    routes: [

        {
            path: "/katriumweb/login",
            name: "login",
            component: () => import("@/views/Login.vue")
        },
        {
            path: "/katriumweb/playground",
            name: "playground",
            component: () => import("@/views/Playground.vue")
        },
        {
            path: "/katriumweb/",
            name: "home",
            component: () => import("@/views/Home.vue"),
            meta: {
                authRequired: true
            }
        },
        {
            path: "/katriumweb/vehicleupdate",
            name: "vehicleupdate",
            component: () => import("@/views//workflows/VehicleUpdate.vue"),
            meta: {
                authRequired: true
            }
        }

    ],
});


router.beforeEach(async (to, from, next) => {

    const authStore = useAuthStore();

    let token = authStore.user? authStore.user.TOKEN : false;
    
    const checkToken = await fetch("*******", {
        method: "GET",
        headers: {
            "Token": `${token}`
        }
    })

    if (to.meta.authRequired) {
        if (!checkToken.ok || !token) {
            localStorage.clear();
            next("/katriumweb/login");
        } else {
            next();
        }
    } else {
        next();
    }
})


export default router;

*** vite.config.js ***

    import { fileURLToPath, URL } from "node:url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  base: "/katriumweb/",
  plugins: [vue()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
});

CodePudding user response:

  1. Remove /katriumweb from each route.
  2. In router.ts:
const router = createRouter({
  history: createWebHistory('/katriumweb'),
  ...
})
  1. configure your server for history mode.
    You basically need to teach the server: when someone accesses a sub-route of /katriumweb (e.g: /katriumweb/login), don't resolve it to index.html in /katriumweb/login/ folder.
    Resolve it to index.html in /katriumweb folder.

Example apache configuration, using .htaccess file:

<IfModule mod_negotiation.c>
  Options -MultiViews
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /katriumweb
RewriteRule ^katriumweb/index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /katriumweb/index.html [L]
</IfModule>
  1. If not obvious, you'll need to place the contents of dist/ folder you get from yarn build into katriumweb/ folder on the server. If you want the build command to generate katriumweb/ inside dist/, use build.outDir in vite.config.js.

CodePudding user response:

Since the app itself only has an index.html file and everything else is done via javascript, when you navigate to /mypage it tries to grab another html file. The Vue Router createWebHistory works this way. A simple fix is to use createWebHashHistory, which uses a hash in order to create the routing.

Otherwise, more solutions are available on the documentation (eg. Netlify supports a redirect property to handle this).

The docs: https://router.vuejs.org/guide/essentials/history-mode.html

  • Related