I'm building a web app in Vue3 and using Vite to serve it during development. The app is split into three parts - management, user and login. Each of these will call the same backend.
The intention is to split my app into three and reuse libraries and components across each section, while bundling only the necessary code in the final build. Also, I want a lightweight login page that detects which type of user has logged in, then redirects him to the relevant section. Hence why I have configured Vite to run in MPA mode.
I've Vite configured as follows (relevant sections only):
rollupOptions: {
input: {
mgmt: resolve(__dirname, './mgmt/index.html'),
user: resolve(__dirname, './user/index.html'),
login: resolve(__dirname, './index.html')
},
appType : 'mpa'
And my JsAppRoot is laid out like this:
vite.config.js
mgmt/index.html
user/index.html
index.html # login
I also use vue router in Html5 history mode. It's configured in mgmt.ts like this:
const router = createRouter({
history: createWebHistory('/mgmt'),
routes: [
// EXCERPTED
{
path: '/room/details',
name: 'room-details',
component: RoomDetails,
meta: {
breadcrumb: [{label: 'Room Details'}],
title: 'Room Details'
}
}
]
});
Now when I run the app, I can see the login page and complete login successfully, then redirect to the relevant part of the app depending on the user role - management or user. Also when I navigate through the app I see the router updating the path correctly - i.e. https://localhost:5173/mgmt/room/details
Yet when I reload the page, I get a 404 and a blank screen. It seems that the router doesn't recognise or like my MPA configuration.
How do I fix this? I've rewritten part of my app to be a SPA, and when in that mode reloading does make the router load the correct path, it means I lose the advantages of modularity.
Sounds like you are missing the fallback routes.
When using HTML 5 history mode, you need to configure your webserver to redirect logical urls to the base url, i.e. https://localhost:5173/mgmt/room/details
should be redirected to https://localhost:5173/mgmt/index.html
(see docs).
During development, you can add redirect rules for the dev server using the server-proxy
option (see doc):
// vite.config.js
export default defineConfig({
server: {
proxy: {
'^/mgmt(?!/index.html)': { // REGEX: redirect calls to /mgmt/... but not /mgmt/index.html
rewrite: (path) => '/mgmt/index.html',
target: 'http://localhost:5173',
},
},
},
})
Depending on how complicated your rewrites get, configuring the dev server directly through a custom Vite plugin might be easier:
// vite.config.js
const rewriteUrlsPlugin = () => ({
name: 'configure-server',
configureServer(server) { // configureServer() is used to configure the dev server
server.middlewares.use((req, res, next) => { // add callback to rewrite urls
if (req.url.startsWith('/mgmt')){
req.url = '/mgmt/index.html'
}
next()
})
},
})
export default defineConfig({
plugins: [
vue(), rewriteUrlsPlugin() // <---- register plugin
],
Does that fix the issue? Keep in mind, you'll need similar rewrites in the production server.