'Error: ENOENT: no such file or directory in express-handlebars
I am using express-handlebars
to load dynamic content in NodeJS
inside app.js
const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");
const pp = require("./util/path.js");
const adminRoutes = require("./routes/admin");
const shopRoutes = require("./routes/shop");
const expressHbs = require("express-handlebars");
const app = express();
app.engine("hbs",expressHbs());
app.set("view engine", "hbs");
app.set("views", "views");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "public")));
app.use("/admin", adminRoutes.routes);
app.use(shopRoutes);
app.use((req, res, next) => {
res.status(404).render("404", { pageTitle: "Page Not Found" });
});
app.listen(3001, "localhost", () => console.log("Listening on 3001 PORT"));
When expressHbs()
function has no param it shows the following error
Error: ENOENT: no such file or directory, open 'C:\dev\nodejs\maximi_course\views\layouts\main.handlebars'
And when i pass an option object to it:
app.engine(
"hbs",
expressHbs({
extname: "hbs",
layoutsDir: path.join(__dirname, "views")
})
);
It shows:
Error: ENOENT: no such file or directory, open 'C:\dev\nodejs\maximi_course\views\main.hbs'
I've searched for a solution but i got no result , Actually i am following a tutorial and i have done the same as teacher did but i got an error.
Lastly thing that i have tried is adding defaultLayout property and it works and load the default but when i change the url to another page it always load the same page which i set as default
Here is project folder and all its contents
Solution 1:[1]
Actually it's a bit annoying problem with express-handlebars
but got it solved as following:
- I had to create a standalone file which's not one of
Routes
and assign its name todefaultLayout
- I had to set the path to
views/layouts/
- I had to to define
extname
to the extension i had defined
app.engine(
"hbs",
expressHbs({
extname: "hbs",
defaultLayout: "main-layout",
layoutsDir: "views/layouts/"
})
);
Solution 2:[2]
I had the same problem and fixed it by using the following method:
app.engine(
"hbs",
expressHbs({
extname: "hbs",
defaultLayout: false,
layoutsDir: "views/layouts/"
})
);
Solution 3:[3]
[email protected] defines the following configuration options
function ExpressHandlebars(config) {
// Config properties with defaults.
utils.assign(this, {
handlebars : Handlebars,
extname : '.handlebars',
layoutsDir : undefined, // Default layouts directory is relative to `express settings.view` + `layouts/`
partialsDir : undefined, // Default partials directory is relative to `express settings.view` + `partials/`
defaultLayout : 'main',
helpers : undefined,
compilerOptions: undefined,
}, config);
If you do not use a default layout you can just set defaultLayout: false
like below
app.engine(
"hbs",
expressHbs({
extname: "hbs",
defaultLayout: false
})
);
Solution 4:[4]
Need to set defaultLayout as false, else "express-handlebars" will search for main.handlebars.
app.engine("hbs", expressHbs({ defaultLayout: false }));
app.set("view engine", "hbs");
app.set("views", "views");
Solution 5:[5]
Node.js/Expressjs
Q. Error: ENOENT: no such file or directory, open 'S:\globle_express\views\layouts\main.handlebars'
Answer.
Rename your layout folder and do layouts
The folder structure of Expressjs should be like this
Solution 6:[6]
Making defaultLayout to false will solve this problem. My code worked fine with me.
app.engine('hbs',hbs(
{
extname:'hbs',
defaultLayout:false,
layoutDir:__dirname+'/views/layout/',
partialsDir:__dirname+'/views/partials/'
}
))
Better to keep folder name as layouts and file name inside is layout.hbs without 's'.
After renaming the folder, my previous code worked with me perfectly.
app.engine('hbs',hbs(
{
extname:'hbs',
defaultLayout:'layout',
layoutDir:__dirname+'/views/layouts/',
partialsDir:__dirname+'/views/partials/'
}
))
Solution 7:[7]
There is no need of creating a layouts folder with a file within it.create 'views' folder and add the file. For instance 'form.handlebars' then do the following according to your code
app.get('/' (req,res)=> {
res.render("contact", {
layout: false,
name: req.body.name,
quote: req.body.quote
});
})
Solution 8:[8]
Include this in your app.js
app.locals.layout = false;
Solution 9:[9]
app.engine(
'hbs',
hbs.express4({
defaultLayout: false,
partialsDir: __dirname + '/views/partials'
})
);
For express 4
Solution 10:[10]
You can simple add this:
app.engine('handlebars', exphbs.engine());
app.set('view engine', 'handlebars')
It worked in my case. Thanks:)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow