I'm having an error serving static views on a Heroku app. Strangely, Heroku seems to append "app" to the front of my static file paths, and I'm not sure why. The path should be "public/views/index.html."
I recently tried this proposed solution from Stack, but it didn't seem to work: Node.js, can't open files. Error: ENOENT, stat './path/to/file'
The get requests from my server:
app.use(express.static(__dirname + '/public'));
app.get('/', function (req, res) {
res.sendFile(__dirname + '/public/views/index.html');
});
// profile page
app.get('/profile', function (req, res) {
// check for current (logged-in) user
req.currentUser(function (err, user) {
// show profile if logged-in user
if (user) {
res.sendFile(__dirname + '/public/views/profile.html');
// redirect if no user logged in
} else {
res.redirect('/');
}
});
});
Does anyone have any idea why Heroku would append "app" to my paths?
All the paths work correctly on a local server. Thanks!
The accepted. solution here of using PWD instead of __dirname is quite wrong. sendFile works on Heroku the same way it works anywhere else:
res.sendFile(path.join(__dirname, 'public', 'views', 'index.html'));
This is because the global __dirname variable inside Heroku is set to /app. Use process.env.PWD instead of __dirname.
Looks like this hasn't had an update in a while, but I ran into the same Heroku root directory confusion, but when I changed my code to use 'path' instead of __dirname, it worked.
path.join(__dirname, '..', 'views', 'email', `${template}.pug`),
Related
I'm trying to get express static working with dynamic subdomain.
Basically http://ratty-doll-4811.localhost:3333 this subdomain is dynamic, and I load static folder based on this subdomain.
My issue is index.html loads but app.js which is in the same directory as index.html, doesn't load.
const subdomain = require('subdomain');
var app = Express()
app.use(subdomain({ base : 'localhost', removeWWW : true }));
app.get('/subdomain/:url', function(req, res, next) {
app.use('', Express.static(path.join(__dirname, 'public')));
res.sendFile('index.html', { root: __dirname + '/public' })
});
Here is the error:
You can't dynamically call app.use() because that will just build up route handlers over and over and they will accumulate indefinitely and be in force for all future requests. You can however, get the request handler from express.static() and call the request handler yourself dynamically.
I don't follow exactly what you're trying to accomplish, but this will show you how you can call it dynamically and then act differently based on whether it found a match of not.
// get express.static() handler
let staticHandler = Express.static(path.join(__dirname, 'public'));
app.get('/subdomain/:url', function(req, res, next) {
staticHandler(req, res, (err) => {
if (err) return next(err);
// it only gets here if the staticHandler didn't find a match and send a response
res.sendFile('index.html', { root: __dirname + '/public' })
});
});
I'm doing a simple node project to practice but i can't manage to serve html file with its css styles.
I believe that it worked fine for me before with the same code but now I don't understand why it doesn't run.
I searched about it and copied some code replacing the directory's name but it doesn't change anything.
Here is my code.
I also tried with path module to join the file name and the directory name.
app.use(express.static('public'));
app.get('/', (req, res)=>{
res.send("Welcome to our website");
});
app.get("/signup", (req, res)=>{
res.sendFile(__dirname + "/index.html");
});
//My directory:
testapp1
--node_modules
--public
--styles.css
--index.html
--app.js
--package.json
--package-lock.json
In the network tab of the developer console, it says that:
status: canceled
type: stylesheet
initiator: index.html
Size: 0B
time: 29ms
waterfall: "nothing"
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function (req, res, next) {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
Try that instead.
How is the index.html (frontend Angular) getting called exactly?
In the tutorial, it was said that by having one of the following routes in route.js, frontend is getting called
app.get('*', function(req, res) {
res.sendfile('./public/index.html');
});
----------or-------------------
app.get('*', function(req, res) {
res.sendfile('__dirname + '/public/index.html');
});
But even after removing that route, index.html is getting opened (or) If I rename index.html as index1.html at route and html file it is showing error.
Have you created a file index1.html in public folder? If yes, Use
res.sendfile('public/index1.html');
OR
var path = require('path');
res.sendFile(path.join(__dirname, '../public', 'index1.html'));
to render index1.html.
Note : sendfile is deprecated.
I am getting the below screen-shot error when I try to serve my client-side code. When I am trying to run node server/server.js:
The below is my server.js code...
app.use(express.static(path.join(__dirname, "public")));
app.use(logger('dev'));
app.use(bodyParser.json({limit: '50mb'}));
app.all('/*', function(req, res, next){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
res.header("Access-Control-Allow-Headers", "Content-type,Accept,X-Access-Token,X-Key");
if(req.method === 'OPTIONS'){
res.status(200).end();
} else {
next();
}
});
app.all("/api/v1/*", [require('./middlewares/validateRequest')]);
app.use("/", require("./routes"));
app.use(function(req, res, next){
var err = new Error("Not found");
err.status = 404;
next(err);
});
Inside my routes/index.js, I have the following for get request.
router.get('*', function(req, res) {
res.sendfile('./public/index.html');
});
Usually when the browser requests a JavaScript file, the server sends an HTML file. This is due to rules like app.get('*'.... So we need to tell the server to send the static files first and then declare the rules, like shown below:
// Declare static folder to be served. It contains the JavaScript code, images, CSS, etc.
app.use(express.static('build'));
// Serve the index.html for all the other requests so that the
// router in the JavaScript application can render the necessary components
app.get('*', function(req, res){
res.sendFile(path.join(__dirname + '/build/index.html'));
//__dirname : It will resolve to your project folder.
});
My folder structure
node(folder)
server.js
-client(f)
-index.html
-views(f)
-js(f)
-ctrl(f)
-service(f)
-app.js
-state.js
and
app.use(express.static('client'));
app.get('/index.html', function (req, res) {
res.sendfile(_dirname + '/index.html');
});
Call this from the browser: http://127.0.0.1:1956/index.html
var server = app.listen(1956, function (req, res) {
var host = server.address().address
var port = server.address().port
console.log("app listening at", host, port)
});
It's working fine for me.
I think this may be caused by your /public/index.html file.
When you include the JavaScript files in the index.html file, there's some problem with the "src" property. Thus it will return a "not found" HTML file instead of the actual JavaScript file.
I found the solution. The Node.js application tries to compile the JavaScript files inside the public folder, that makes a mistake; you defined the public folder like this:
app.use(express.static(path.join(__dirname, 'public')));
Try to define it using a virtual directory by adding a specific virtual folder name like this:
app.use('/static', express.static(path.join(__dirname, 'public')));
This should be work;
I guess part of the problem is in your router
In your routes/index.js change the get request to
router.get('/', function(req, res) {
res.sendfile('./public/index.html');
});
Also are you pipe-lining your assets using gulp or something similar? If not then how are you serving your assets?
I recommend you either serve your assets statically or use gulp
My project have this following structure.
server.js
/node_modules
/build
vendor.js
main.js
index.html
I'm using express, and AngularJS's ui-router.
In server.js I have this code:
app.get('/*', function(req, res) {
res.sendFile(__dirname + '/build/index.html');
});
And locally it is working if I pass localhost:8080/hellothere, I get the correct page but when I've deployed, it doesn't.
Within the application if use the links to navigate the routes run, the URL is modified to /hellothere, but if I update the page or try to go straight to the absolute URL I get:
Cannot GET /hellothere
I'm already have tryied put:
app.get('/page1', function(req, res) {
res.sendFile(__dirname + '/build/index.html');
});
app.get('/page2', function(req, res) {
res.sendFile(__dirname + '/build/index.html');
});
...
And the behavior is the same of '/*'. Fine local, broke on cloud.
Any idea what's happening here?
homolog Website link
And locally it is working if I pass localhost:8080/hellothere, I get
the correct page but when I've deployed, it doesn't.
The possible reason might be after deploying your base url might be domainname.com/appname and your local code is for localhost:portNumber not for localhost:portNumber/appname
So modify your path to
app.get('/appname/hellothere', function(req, res) {
res.send("hellothere is working");
});
instead of
app.get('/hellothere', function(req, res) {
res.send("hellothere is working");
});
To run it locally, now you will need localhost:portNumber/appname/hellothere