
Last updated: Apr 5, 2024
Reading timeยท4 min

The Express.js error "Failed to lookup view "X" in views directory" occurs
when you incorrectly specify the path to the view in the call to the
res.render() method.
To solve the error, configure your view engine and specify the correct path to the view.

Here is a minimal example of correctly configuring a view engine in Express.js.
// ๐๏ธ using require() CommonJS syntax const express = require('express'); const path = require('path'); const app = express(); app.use( '/static', express.static(path.join(__dirname, 'public')), ); app.set('view engine', 'pug'); app.get('/', (req, res) => { res.render('index', { title: 'bobbyhadz.com', message: 'Express.js example', }); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
If you use the ES6 modules import/export syntax, use the following code sample instead.
// ๐๏ธ using ES6 import/export syntax import express from 'express'; import path from 'path'; import {fileURLToPath} from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); app.use( '/static', express.static(path.join(__dirname, 'public')), ); app.set('view engine', 'pug'); app.get('/', (req, res) => { res.render('index', { title: 'bobbyhadz.com', message: 'Express.js example', }); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
And here is the index.pug file that is located in my views directory.
html head title= title body h1= message

The example uses the pug view engine but you can use any other engine.
npm install pug
By default, Express looks for your views (your pug, ejs, mustache templates) in
a views directory located at the root of your project (where your
package.json file is).
index.js package.json views/ โโโ index.pug public/ โโโ styles.css
The error message means that Express couldn't find the template file in your
views directory.
// ๐๏ธ using require() CommonJS syntax const express = require('express'); const path = require('path'); const app = express(); app.use( '/static', express.static(path.join(__dirname, 'public')), ); app.set('view engine', 'pug');
Here is the equivalent ES6 Modules snippet.
// ๐๏ธ using ES6 import/export syntax import express from 'express'; import path from 'path'; import {fileURLToPath} from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); app.use( '/static', express.static(path.join(__dirname, 'public')), ); app.set('view engine', 'pug');
The example uses pug as the view engine, but you can use any other view
engine, e.g. ejs.
app.set('view engine', 'ejs');
The code sample assumes that you store your static (JS, CSS, HTML) files in a
public directory that is located in the root folder (where your package.json
file is located).
index.js package.json views/ โโโ index.pug public/ โโโ styles.css
By default, express looks for a views directory in your root folder.
path.join() method (as shown above) when setting the
static directory.Using the path.join() method ensures that the specified path is going to be
correct on Windows, Linux and macOS.
For example, the following path breaks on Windows.
// โ๏ธ this breaks on Windows app.use(express.static(__dirname + '../public'));
Instead, you should use the path.join() method.
app.use(express.static(path.join(__dirname + '../public')));
The '../' prefix means "go one directory up".
index.pug (or index.ejs
depending on your views engine) file located in a views directory in your
root folder.
If you don't have an index.xyz file in your views directory, the "Failed to
lookup view" error is raised.
The second parameter we pass to the app.set method is basically the extension
of the template file.
// ๐๏ธ ejs view engine app.set('view engine', 'ejs'); // ๐๏ธ pug view engine app.set('view engine', 'pug');
Assuming you have the following route handler.
app.get('/', (req, res) => { res.render('index', { title: 'bobbyhadz.com', message: 'Express.js example', }); });
Then Express is going to look for an index.pug or index.ejs file in your
views directory.
// ๐๏ธ where template files are located app.set('views', './views'); // ๐๏ธ what view engine to use (pug, ejs, etc) app.set('view engine', 'pug');
The views setting determines the directory where the template files are
located.
By default, the views setting is set to look for your template files in the
views directory at the root of your project (where your package.json file
is).
index.js package.json views/ โโโ index.pug public/ โโโ styles.css
If you need to change the views directory to something else, use the
app.set() method.
For example, the following code sample changes the views directory to
my-views.
// ๐๏ธ using require() CommonJS syntax const express = require('express'); const path = require('path'); const app = express(); app.use( '/static', express.static(path.join(__dirname, 'public')), ); // ๐๏ธ change views directory to my-views app.set('views', path.join(__dirname, 'my-views')); app.set('view engine', 'pug');
Here is the equivalent example using the ES6 modules import/export syntax.
// ๐๏ธ using ES6 modules import/export syntax import express from 'express'; import path from 'path'; import {fileURLToPath} from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); app.use( '/static', express.static(path.join(__dirname, 'public')), ); app.set('views', path.join(__dirname, 'my-views')); app.set('view engine', 'pug');

As shown in the screenshot, the views are now stored in the my-views
directory.
index.js package.json my-views/ โโโ index.pug public/ โโโ styles.css
To make sure your path is correct, always use the path.join() method.
You can also console.log() the call to path.join() when debugging to verify
the specified path is correct.
You can learn more about the related topics by checking out the following tutorials: