express-handlebars icon indicating copy to clipboard operation
express-handlebars copied to clipboard

No such file or directory

Open itotallyrock opened this issue 9 years ago • 13 comments

I'm running into the same issue and it involves the differences in operating systems. This is because the application works as intended on windows, but fails on linux with Error: ENOENT: no such file or directory, open '/views/layouts/main.handlebars'

Here is my file structure.

|-- index.js
|-- package.json
|-- public
|   |-- css
|   |   `-- global.css
|   |-- img
|   `-- js
|       `-- main.js
`-- views
    |-- 404.handlebars
    |-- index.handlebars
    |-- layouts
    |   `-- main.handlebars
    `-- partials
        |-- footer.handlebars
        |-- nav.handlebars
        `-- title.handlebars

and here is part of the index.js file

app.set('views', path.join(__dirname, './views'));
app.engine('handlebars', expressHandlebars({
    defaultLayout: 'main'
}));
app.set('view engine', 'handlebars');

While I was making this issue, I ran into another error Error: Failed to lookup view "index" in views directory "/views" Which contains no reference back to express-handlebars but only mentions express in the stack.

I'm assuming this is just a simple mistake on my part but it might be worth documenting for people like me who don't quite understand the subtle differences between linux and windows.

itotallyrock avatar Oct 28 '16 04:10 itotallyrock

Try using path.resolve instead of path.join and see if it helps.

sgnl avatar Jan 19 '17 21:01 sgnl

I am also experiencing this issue. I use app.set('views', __dirname + '/views'); but the ENOENT error says it is trying to access project-name/views/layouts/main.handlebars instead of the expected project-name/src/views/layouts/main.handlebars'.

kas avatar Apr 11 '17 16:04 kas

I ran into the same issue, and could solve it by setting the layoutDir and partialsDir option as follows:

app.engine('.hbs', exphbs({
    extname: '.hbs',
    defaultLayout: 'main',
    partialsDir: path.join(__dirname, 'views/partials'),
    layoutsDir: path.join(__dirname, 'views/layouts')
  }));
app.set('view engine', '.hbs');
app.set('views',path.join(__dirname,'views'))

ndeufemia avatar May 17 '17 14:05 ndeufemia

How to reproduce this issue:

  • Make sure you have a layout in the views/layouts directory.
  • Run project from a directory different to the app's directory: node path-to-app.

From this discussion it seems that the bug is due to pure default path resolving in express-handlebars.

This issue is fixed by this PR but not published yet.

DmitryMyadzelets avatar Sep 25 '17 17:09 DmitryMyadzelets

For anyone out there who doesn't have an layouts or layout folder and is having the same issue. Try this in the rendering of the page: res.render('index', {layout: false});

erickhora avatar Jun 24 '19 15:06 erickhora

Is there a way to set the set the default value of layout to false. I'm hoping to avoid updating all of my render functions from something like:

res.render("index");

to

res.render("index", {layout: false});

johnnyodonnell avatar Jul 18 '19 01:07 johnnyodonnell

defaultLayout: null should work

UziTech avatar Jul 18 '19 01:07 UziTech

@johnnyodonnell

app.locals.layout = false

knoxcard avatar Aug 05 '19 14:08 knoxcard

const expressHandlebars  = require('express-handlebars');

app.engine('hbs', expressHandlebars({
    defaultLayout: '',
}));

app.set('view engine', 'hbs');
app.set('views', 'views');

ahmedatef1610 avatar Aug 29 '19 16:08 ahmedatef1610

For anyone out there who doesn't have an layouts or layout folder and is having the same issue. Try this in the rendering of the page: res.render('index', {layout: false});

Thanks Its Working...

pulkit5ingh avatar Oct 30 '19 18:10 pulkit5ingh

For anyone out there who doesn't have an layouts or layout folder and is having the same issue. Try this in the rendering of the page: res.render('index', {layout: false});

Thanks Its Working...

For anyone out there who doesn't have an layouts or layout folder and is having the same issue. Try this in the rendering of the page: res.render('index', {layout: false});

Thanks Its Working...

but what if we have layout but still showing such problem

Alpha4733 avatar Jan 17 '20 08:01 Alpha4733

This solved my issue:

app.engine('hbs',handlebars({ 
    layoutsDir: path.join(__dirname,'views','layouts'), 
    defaultLayout: 'main-layout', 
    extname: 'hbs'
}))

muhammadwarisali avatar Apr 10 '20 12:04 muhammadwarisali

I had a silly mistake as: extName: '.hbs' instead of extname: '.hbs'

forcetrekker avatar Jun 21 '20 22:06 forcetrekker