Error: ENOENT: no such file or directory in express-handlebars

Abdulrahman Falyoun picture Abdulrahman Falyoun · Jun 28, 2019 · Viewed 7.3k times · Source

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

Directory

Answer

Mahmood Afzali picture Mahmood Afzali · Dec 5, 2019

I had the same problem and fixed it by using the following method:

app.engine(
  "hbs",
  expressHbs({
    extname: "hbs",
    defaultLayout: false,
    layoutsDir: "views/layouts/"
  })
);