This is the structure of my project.
app
-controllers
index.server.controller.js
-models
-routes
index.server.routes.js
-views
index.ejs
config
-express.js
I set the view directory in my express.js file:
app.set('views', '../app/views');
app.set('view engine', 'ejs');
And this is in my controller file:
exports.render = function(req,res) {
res.render('index' , {
title: 'welcome to this page'
})
};
Whenever i open localhost i get
Error: Failed to lookup view "index" in views directory "../app/views/"
You're giving it a wrong path. Try this
app.set('views', __dirname + '/../app/views');
I am not able to use Swig templates with Express for Node.
I get the following error :
Error: Failed to lookup view "index" in views directory
The Swig templates are not being compiled into .html files
My code is below :
var express = require('express');
var cons = require('consolidate');
var swig = require('swig');
var app = express();
//Set template engine
app.engine('html', cons.swig);
app.set('view engine', 'html');
app.set('views', __dirname + '/views')
// Disable Express's and Swig Cache
app.set('view cache', false);
swig.setDefaults({ cache: false });
app.get('/', function(req, res){
res.render('index', {'title': 'Design'});
});
app.listen(3000);
I just had the same issue. In order to use swig templates with the swig extension working you can follow the swig Docs and then replace the two following lines with
app.engine('html', cons.swig);
app.set('view engine', 'html');
with
app.engine('swig',swig.renderFile);
app.set('view engine', 'html');
Should look something like this.
var express = require('express');
var swig = require('swig');
var app = express();
// view engine setup
// This is where all the magic happens!
app.engine('swig', swig.renderFile);
app.set('view engine', 'swig');
app.set('views', path.join(__dirname, 'views'));
app.set('view cache', false);
swig.setDefaults({ cache: false });
Expressjs 4.x docs app.engine
The app.engine takes a extension and a callback. So to all files found with the swig extension have a callback of swig.renderFile. Each file with generated to HTML.
Expressjs 4.x docs app.set
Setting the view engineto swig is setting the default engine extension to use when omitted. Were also saying that all the views can be found in the /blaha/blaha/blah/views directory.
NOTE: All files in the views directory must end int .swig.
So just a friendly reminder make sure when you "include" or reference another template you must put the filename and extension it the path. ex: layout.swig. I hope this gets your project working.
As explained here:
http://mherman.org/blog/2015/08/23/primer-on-swig-templating/#.VhWxVvlVhBc
Simply use .html files instead of .swig files. I don't know where you got the idea of using .swig files. Maybe an older version? I dunno. The current Swig's documentation Basic Usage shows using a .html file as well:
http://paularmstrong.github.io/swig/docs/
If you rename your index.swig to index.html I would expect it to work fine.
Yes, i think it's more semantic to store your templates as .swig files, if you using SWIG as template engine. So, all you need is set 'swig' as engine:
// view engine setup
app.engine('swig', swig.renderFile);
app.set('view engine', 'swig');
app.set('views', path.join(__dirname, 'views'));
Then you can store your views like ./views/layout.swig
for latest version of swig we need to include swig package which needed to installed through package manager or package.json file
var express = require('express');
var swig = require('swig');
var app = express();
// Here we need to set up and engine as per latest version of swig
//for latest version of swig we need to include swig package which //needed to installed through package manager or package.json file
app.engine('swig', swig.renderFile);
app.set('view engine', 'swig');
app.set('views', path.join(__dirname, 'views'));
app.set('view cache', false);
swig.setDefaults({ cache: false });
//Here we are setting cache defaults to false.
`
I have a test node.js server running the following code:
var app = require('express')();
app.set('views', __dirname + '/public');
app.set('view engine', 'jade');
app.get('/', function(req, res) {
res.render('index.jade', {name: "Test data."});
});
app.listen(3000);
This code works find. I'm wondering what the best practices are for choosing a .jade file based upon the url without hard-coding it, kind of like you might for html files using express.static. Of course, I don't want there to be a direct path correlation either (instead assigning different routes to different directories or groups of directories.) There doesn't seem to be a whole lot of solid information on the subject. Anything would be helpful. Thanks.
with utilization of splats you could do something like this:
var app = require('express')();
app.set('view engine', 'jade');
// /foo/Sam/path/to/view.jade yield a rendering of 'path/to/view.jade' with name: 'Sam'
app.get('/foo/:name/*.*', function(req, res) {
res.render(req.params.join('.'), {name: req.params.name});
});
app.listen(3000);
How can I use a subfolder for my 'views'?
In the main 'app.js' I've set the root folder for the views like so:
app.configure(function(){
app.set('view engine', 'jade');
app.set('views', __dirname + '/apps' );
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(__dirname + '/apps' ));
app.use(app.router);
});
And my controller loos like this:
module.exports = function(req, res, base) {
res.render( 'hello/views/');
};
The folder looks like this:
./apps/hello/views/index.js
But still it can't find it. "ERROR: Failed to lookup view "hello/views"
Thanks!
Actually, I made a vastly better solution.
In the app configuration I just set the default view like so:"
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
Later on I inlcude a boot.js (based on the mvc example of expressjs ) in which I include the following:
// allow specifying the view engine
if (obj.engine) app.set('view engine', obj.engine);
app.set('views', __dirname + '/../apps/' + name + '/views');
This will override the view folder to the one specified in the folder 'apps/xxx/views' and will even allow you to specify a new viewtype in the root of that folder like so:
// filename = /apps/hello/index.js
exports.engine = 'jade';
// Render the indexpage
exports.index = function(req, res, next){
res.render('hello');
};
I am surprised that your self answer works, since you should be telling express to render a particular view, and hello/views is a folder. However I'm not familiar with the code pattern you're using for your controller (the base argument is what's throwing me off, since Express middleware uses function(req,res,next).)
My routes look like this:
app.set('views', __dirname + '/apps' );
...
app.get('/hello', function(req,res){
res.render('hello/views/index')
});
In this case ./apps/hello/views/index.jade is a jade file, not a javascript file. If your templates are javascript, perhaps you should set view engine to something other than jade.
You can set views as array of paths
app.set('views', [path.join(__dirname, 'views/users/'), path.join(__dirname, 'views')])
You can check the resulting paths using app.get('views'); which should return an array.
[/server/views/users/, /server/views]
Express will search through the array for available paths. You can then render with just the file name like this
res.render( 'index');
res.render( 'profile');
I fixed this problem by setting the basis view to the root of the directory like so:
app.set('views', __dirname);
And the added the folders from the root on in the controller like so:
res.render( 'apps/hello/views/');
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.
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.
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'));
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");
});
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.
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
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');
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:
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");
});
use this code to solve the issue
app.get('/', function(req, res){
res.render("index");
});
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.
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.
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);
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.
I had the same issue and could fix it with the solution from dougwilson: from Apr 5, 2017, Github.
I changed the filename from index.js to index.pug
Then used in the '/' route: res.render('index.pug') - instead of res.render('index')
Set environment variable: DEBUG=express:view
Now it works like a charm.
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.
I had the same issue. Then just check the file directory in your explorer. Sometimes views folder isn't present.
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
app.get("/", (req, res) => {
res.render("home");
});
// the code below brought the error
app.get("/", (req, res) => {
res.render("/");
})
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