0

My node.js app can't find the public folder. I've tried using connect static and express static from this answer: static files with express.js and also this answer: File not found in Node.js

But I still can't get it working. I get the content of the page I try to display, but not any of the links to css and js files.

Any ideas? This is my app.js file.

var express = require('express'),
post = require('./routes/posts'),
web = require('./routes/web'),
http = require('http'),
stylus = require('stylus'),
nib = require('nib'),
path = require('path');

var app = express();

function compile(str, path) {
    return stylus(str).set('filename', path).use(nib());
}

app.configure(function () {

app.set('views', __dirname + '/views');
app.set('view engine', 'jade');

app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());
app.use(app.router);
app.use(stylus.middleware({src: __dirname + '/public', compile: compile}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.bodyParser({ keepExtensions: true, uploadDir: __dirname + '/upload/photos' }));
});

//app.use(app.router);

//Web
app.get('/',        web.frontPage); 

app.post('/posts',           post.findAllPosts);
app.post('/posts/:id',       post.findPostById);
app.post('/postAdd',          post.addPost);
app.put('/posts/:id',       post.updatePost);
app.delete('/posts/:id',    post.deletePost); 

app.get('*', function(req, res){
    res.render('404');
});

http.createServer(app).listen(80);
console.log('Listening on port 80...');
Community
  • 1
  • 1
just_user
  • 11,769
  • 19
  • 90
  • 135

1 Answers1

7

Your problem is caused by this:

app.get('*', function(req, res){
  res.render('404');
});

Because you're declaring the app.router middleware (which handles that catch-all route) before the static middleware, the router gets all the requests for static files too, and if they aren't handled by any of your other routes, it will generate a 404.

The solution would be to move the static middleware to before the router. The same also needs to be applied to the Stylus middleware and the bodyParser middleware, to make sure they are called before your routes:

app.use(stylus.middleware({src: __dirname + '/public', compile: compile}));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.bodyParser({ keepExtensions: true, uploadDir: __dirname + '/upload/photos' }));
app.use(app.router);

(although it seems that you can skip the bodyParser middleware, since you're using the json, urlencoded and multipart middlewares already; the bodyParser middleware is just a very thin wrapper around those three)

robertklep
  • 198,204
  • 35
  • 394
  • 381