80

Note: my auto answer at end of the post

I'm trying to make a better experience of nodeJS and i don't really like to get all the script in one file.

so, following a post here i use this structure

./
 config/
   enviroment.js
   routes.js
 public/
   css/
     styles.css
   images
 views
   index
     index.jade
   section
     index.jade
   layout.jade
 app.js

My files are right now:

app.js

var express = require('express');
var app = module.exports = express.createServer();

require('./config/enviroment.js')(app, express);
require('./config/routes.js')(app);

app.listen(3000);

enviroment.js

module.exports = function(app, express) {
    app.configure(function() {
        app.use(express.logger());
        app.use(express.static(__dirname + '/public'));
        app.set('views', __dirname + '/views');
        app.set('view engine', 'jade'); //extension of views

    });

    //development configuration
    app.configure('development', function() {
        app.use(express.errorHandler({
            dumpExceptions: true,
            showStack: true
        }));
    });

    //production configuration
    app.configure('production', function() {
        app.use(express.errorHandler());
    });

};

routes.js

module.exports = function(app) {

    app.get(['/','/index', '/inicio'], function(req, res) {
        res.render('index/index');
    });

    app.get('/test', function(req, res) {
        //res.render('index/index');
    });

};

layout.jade

!!! 5
html
    head
        link(rel='stylesheet', href='/css/style.css')
        title Express + Jade
    body
        #main
            h1 Content goes here
            #container!= body

index/index.jade

h1 algoa

The error i get is:

Error: Failed to lookup view "index/index" at Function.render (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\application.js:495:17) at render (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\response.js:614:9) at ServerResponse.render (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\response.js:638:5) at c:\xampp\htdocs\nodejs\buses\config\routes.js:4:7 at callbacks (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:177:11) at param (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:151:11) at pass (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:158:5) at Router._dispatch (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:185:4) at Object.router [as handle] (c:\xampp\htdocs\nodejs\buses\node_modules\express\lib\router\index.js:45:10) at next (c:\xampp\htdocs\nodejs\buses\node_modules\express\node_modules\connect\lib\proto.js:191:15)

But i don't really know what is the problem...

I'm starting thinking is because the modules exports...

Answer: Far away the unique solution i found is to change the place i defined app.set('views') and views engine

I moved it to the app.js and now is working well.

var express = require('express');
var app = module.exports = express.createServer();


require('./config/enviroment.js')(app, express);

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

require('./config/routes.js')(app);

app.listen(3000);

I don't really understand the logic behind this but i gonna supose it have one.

nax
  • 1,184
  • 1
  • 8
  • 19
  • I suppose you're still on express 2.x, since things are a bit different in 3.x – mihai Apr 18 '12 at 19:25
  • may be that. i'm following guides from http://expressjs.com but i don't see any related of express3 :s – nax Apr 18 '12 at 19:27
  • yeah it's in still in alpha. if you installed recently with npm you should have it (3.0.0alpha). Better do an `npm ls` to see what version you have. – mihai Apr 18 '12 at 19:29
  • Sorry i forgot to add, i have 3.0.0alpha1 there is any way i can use the v2 or, if it's better get any documentation? – nax Apr 18 '12 at 19:30
  • When the question's auto answer is better than the accepted answer... – Marcel May 16 '16 at 18:26

21 Answers21

43

Adding to @mihai's answer:

If you are in Windows, then just concatenating __dirname' + '../public' will result in wrong directory name (For example: c:\dev\app\module../public).

Instead use path, which will work irrespective of the OS:

var path = require ('path');
app.use(express.static(path.join(__dirname + '../public')));

path.join will normalize the path separator character and will return correct path value.

Zeeshan Hassan Memon
  • 8,105
  • 4
  • 43
  • 57
Veera
  • 32,532
  • 36
  • 98
  • 137
  • Thanks! I used a slightly different solution (on Windows) from the help of this response: app.set('views', __dirname + '/../views'); AND app.use($.express.static($.path.join(__dirname, '/../public'))); – Lucas Sep 10 '13 at 12:50
39

npm install express@2.5.9 installs the previous version, if it helps.

I know in 3.x the view layout mechanic was removed, but this might not be your problem. Also replace express.createServer() with express()

Update:

It's your __dirname from environment.js
It should be:

app.use(express.static(__dirname + '../public'));
Community
  • 1
  • 1
mihai
  • 37,072
  • 9
  • 60
  • 86
  • it's not a version problem... i installed 2.5.9 and still same error – nax Apr 18 '12 at 20:07
  • 1
    i get all the app code and i putted it all in the same app.js and it's working.. so... its the module.exports extructure that is failing some way... – nax Apr 18 '12 at 20:12
  • oh sh***, you have right... i just thinking in the way php do requires... ok! that fix the problem :D thanks! – nax Apr 18 '12 at 20:36
  • Not sure what were those two dots supposed to fix, but they certainly didn't fix anything for me... – Tomáš Zato Nov 08 '16 at 21:24
  • @TomášZato The two dots in `express.static(__dirname + '../public')` denotes "the previous directory from **___dirname**. If **___dirname** was set to */app/private/*, `'../public'` would change it to */app/public/*. – Sometowngeek Nov 10 '17 at 04:16
16

It is solved by adding the following code in app.js file

app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.set('views', __dirname);

app.get('/', function(req, res){
    res.render("index");
});
Codemaker2015
  • 12,190
  • 6
  • 97
  • 81
13

I had the same error at first and i was really annoyed. you just need to have ./ before the path to the template

res.render('./index/index');

Hope it works, worked for me.

Christian Gollhardt
  • 16,510
  • 17
  • 74
  • 111
  • 1
    Similar answer to this worked for me (in 2019). Had to put '../index' instead of just 'index' to get it look for the file one level up. – Ant Apr 11 '19 at 14:43
  • This solved my issue. Thanks. – Moss Sep 19 '21 at 06:47
8

You could set the path to a constant like this and set it using express.

const viewsPath = path.join(__dirname, '../views') 
app.set('view engine','hbs')

 app.set('views', viewsPath)

 app.get('/', function(req, res){

 res.render("index");

});

This worked for me

Harish_Madugula
  • 187
  • 1
  • 2
  • 8
3

Check if you have used a proper view engine. In my case I updated the npm and end up in changing the engine to 'hjs'(I was trying to uninstall jade to use pug). So changing it to jade from hjs in app.js file worked for me.

 app.set('view engine','jade'); 
3

In my case, I solved it with the following:

app.set('views', `${__dirname}/views`);
app.use(express.static(`${__dirname}/public`));

I needed to start node app.min.js from /dist folder.

My folder structure was:

Start app from /dist

piraces
  • 1,320
  • 2
  • 18
  • 42
Maksat
  • 41
  • 3
2

This problem is basically seen because of case sensitive file name. for example if you save file as index.jadge than its mane on route it should be "index" not "Index" in windows this is okay but in linux like server this will create issue.

1) if file name is index.jadge

app.get('/', function(req, res){
      res.render("index");
});

2) if file name is Index.jadge

app.get('/', function(req, res){
      res.render("Index");
});
1

use this code to solve the issue

app.get('/', function(req, res){
    res.render("index");
});
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
  • 5
    would help if you say WHY it should help, what it actually does. – jwenting Sep 01 '16 at 13:32
  • first i use app.use(express.static(__dirname + '../public')); code still the problem is exist then i use the above code after that i fixed the issue. The meaning of the code is when localhost:3000 goes at the time available index.hjs was rendered by using the view engine like hjs in desired directory. – KARTHIKEYAN.A Sep 01 '16 at 14:01
1

Just noticed that I had named my file ' index.html' instead for 'index.html' with a leading space. That was why it could not find it.

Sam Denty
  • 3,693
  • 3
  • 30
  • 43
Bobby
  • 11
  • 1
1

This error really just has to do with the file Path,thats all you have to check,for me my parent folder was "Layouts" but my actual file was layout.html,my path had layouts on both,once i corrected that error was gone.

Hilary Mwape
  • 425
  • 1
  • 4
  • 15
1

i had the same problem but, i change the name of the file from index.html to index.ejs and works!!!!

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
    res.render('index');
});

router.get('/contact', (req, res) => {
  res.render('contact', { title: 'Contact Page' });
});

module.exports = router;

and index.js

const express = require('express');
const morgan = require('morgan');
const path = require('path');
const app = express();



//settings
app.set('port', 4000);
app.set('views', path.join(__dirname,'views'));
app.set('view engine', 'ejs');

//middlewares

//routes
app.use(require('./routes'));

//static files

//listening
app.listen(app.get('port'), () => {
  console.log('Server is running at http://localhost:'+app.get('port')+'/');
});

update: add this in index:

app.engine('html', require('ejs').renderFile);

0

I change the views folder name to views_render and also facing the same issue as above, so restart server.js and it works for me.

0

I had the same issue and could fix it with the solution from dougwilson: from Apr 5, 2017, Github.

  1. I changed the filename from index.js to index.pug
  2. Then used in the '/' route: res.render('index.pug') - instead of res.render('index')
  3. Set environment variable: DEBUG=express:view Now it works like a charm.
Chris
  • 310
  • 4
  • 14
0

I had this issue as well on Linux

I had the following

  res.render('./views/index')

I changed it too
  res.render('../views/index')

Everything is now working.

0

I had the same issue. Then just check the file directory in your explorer. Sometimes views folder isn't present.

0

In my case, I was deploying my web app on a Windows Server and I had a service set up to run a .bat file with only one line as content:

node D:\webapp\app.js

But this was not enough. I also had to change the directory before that, so I added the following line at the beginning of the .bat file:

cd D:\webapp
0
app.get("/", (req, res) => {
  res.render("home");
});

// the code below brought the error

app.get("/", (req, res) => {
  res.render("/");
})
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
  • 2
    Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P Jun 24 '22 at 15:57
0

i actually came across this problem too. What i did was i moved my file from layouts to views and it worked. I suggest you to check if the file you have is in views or in another folder cause, if it is in another folder other than views(or even if the folder is inside of another folder in views), it will give you an error. Just try moving the file to views. It will work for sure.

  • Hi, question is 10 years old, and already has an accepted answer. While answering, be sure to include code snippets, or useful docs, Thank you, and read [how to answer](https://stackoverflow.com/help/how-to-answer) – pierpy Mar 05 '23 at 11:37
-1

I was facing this error because i mistakenly deleted my error.ejs file and it was being called in app.js file and was not found in views as it was already deleted by me

-1

Failed to lookup view "index" in views directory "D:\Express js Website\server\views"

That is problem when we are working with hbs handlebars. This problem is solved by putting my view folder in my server directory.

Your project structure should be this way:

project-root/
├── client/
│   ├── ...
│   └── (your client-side files)
├── server/
│   ├── views/
│   │   └── index.hbs
│   └── your-server-file.js
├── ...
├── package.json
└── ...

Then type cd server so you are in the server folder. After this type nodemon app.js and your Project will run.

LW001
  • 2,452
  • 6
  • 27
  • 36