Serving VueJS Builds via Express.js using history mode
12,897
Solution 1
Have a look at connect-history-api-fallback that is referenced in the vue docs. This should solve your problems.
Example using connect-history-api-fallback
var express = require('express');
var history = require('connect-history-api-fallback');
var app = express();
// Middleware for serving '/dist' directory
const staticFileMiddleware = express.static('dist');
// 1st call for unredirected requests
app.use(staticFileMiddleware);
// Support history api
// this is the HTTP request path not the path on disk
app.use(history({
index: '/index.html'
}));
// 2nd call for redirected requests
app.use(staticFileMiddleware);
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
Solution 2
The very simpler one if anyone wants to use
Just add this below all the valid routes and above app.listen
app.all("*", (_req, res) => {
try {
res.sendFile('/absolute/path/to/index.html');
} catch (error) {
res.json({ success: false, message: "Something went wrong" });
}
});
Make sure you have included
app.use(express.static('/path/to/dist/directory'));
Author by
tbhaxor
I do full-stack developer to fund my cybersecurity and machine learning research.
Updated on June 13, 2022Comments
-
tbhaxor almost 2 years
I want to serve vue js
dist/
via express js. I am using history router in vue js app.The following are the api calls
- api/
- s-file/sending/:id
- terms/get/:which
As i have figured out a solution in python here. I don't know how to do it in node js with
express
The code i am using right now is
app.use(function (req, res, next) { if (/api/.test(req.url)) next(); else { var file = ""; if (req.url.endsWith(".js")) { file = path.resolve(path.join(distPath, req.url)) res.header("Content-Type", "application/javascript; charset=utf-8"); res.status(200); res.send(fs.readFileSync(file).toString()); } else if (req.url.endsWith(".css")) { file = path.resolve(path.join(distPath, req.url)) res.header("Content-Type", "text/css; charset=utf-8"); res.status(200); res.send(fs.readFileSync(file).toString()); } else { file = path.resolve(path.join(distPath, "index.html")) res.header("Content-Type", "text/html; charset=utf-8"); res.status(200); res.send(fs.readFileSync(file).toString()); } } })
-
tbhaxor over 5 yearsit will not work for vue routerlinks i.e fallbacks and moreover i am getting
Cannot GET /
-
Benno over 5 yearsMy bad, have a look at the use of
connect-history-api-fallback
in my updated answer -
LOG_TAG almost 5 yearsError: Forbidden Your client does not have permission to get URL / from this server after deploying to docker !! what does that mean ?
-
Benno almost 5 years@LOG_TAG this error could have many causes either in your hosting configuration or in your server code. Consider opening a separate question where you give all the background information needed: (What are you trying to do? What is working? What isn’t? What have you tried so far)
-
LOG_TAG almost 5 years@Benno sure thanks for responding, I'm dealing with same 'Serving VueJS Builds via Express.js" using google cloud run via gcloud! wondering it's going to be duplicate one :)
-
Benno almost 5 years@LOG_TAG your question seems to be specific to setting up the docker hosting environment - that is out of scope for this question.
-
Abhilash KK over 4 years@Benno I tried both ways, but nothing working. do I need to change anything in vuejs build?
-
Benno over 4 years@Abhilash Please check the Vue docs here router.vuejs.org/guide/essentials/history-mode.html and make sure you did enable history mode in the router. If you don’t get it to work, please consider opening a new question and provide info on what you’re trying to do.
-
gbengaoyetade about 4 yearsWhy is there an "async" when "await" is not being used in the function?
-
Admin almost 3 yearsCan i serve more then one vuejs app using that middleware ? like serving the app and an admin page, each one of them as a separate vue app
-
Christopher Franko about 2 yearsMy man. You're the real mvp.