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: