Error: Failed to lookup view "X" in views directory [Fixed]

avatar
Borislav Hadzhiev

Last updated: Apr 5, 2024
4 min

banner

# Error: Failed to lookup view "X" in views directory [Fixed]

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.

failed to lookup view in views directory

Here is a minimal example of correctly configuring a view engine in Express.js.

index.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.

index.js
// ๐Ÿ‘‡๏ธ 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.

views/index.pug
html head title= title body h1= message

correct directory structure

The example uses the pug view engine but you can use any other engine.

shell
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).

shell
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.

# Things to note when solving the error

  1. Make sure to configure your view engine and your static root directory correctly.
index.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');

Here is the equivalent ES6 Modules snippet.

index.js
// ๐Ÿ‘‡๏ธ 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.

index.js
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).

shell
index.js package.json views/ โ””โ”€โ”€ index.pug public/ โ””โ”€โ”€ styles.css

By default, express looks for a views directory in your root folder.

  1. Make sure to use the 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.

index.js
// โ›”๏ธ this breaks on Windows app.use(express.static(__dirname + '../public'));

Instead, you should use the path.join() method.

index.js
app.use(express.static(path.join(__dirname + '../public')));

The '../' prefix means "go one directory up".

  1. The code sample above assumes that you have an index.pug (or index.ejs depending on your views engine) file located in a views directory in your root folder.

correct directory structure

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.

index.js
// ๐Ÿ‘‡๏ธ ejs view engine app.set('view engine', 'ejs'); // ๐Ÿ‘‡๏ธ pug view engine app.set('view engine', 'pug');

Assuming you have the following route handler.

index.js
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.

  1. There are 2 settings that are used to configure your view engine.
index.js
// ๐Ÿ‘‡๏ธ 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).

shell
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.

index.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')), ); // ๐Ÿ‘‡๏ธ 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.

index.js
// ๐Ÿ‘‡๏ธ 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');

change default views directory

As shown in the screenshot, the views are now stored in the my-views directory.

shell
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.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev