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

The Node.js and Express "TypeError: path must be absolute or specify root to
res.sendFile" occurs when we pass a relative path to the res.sendFile
method.
To solve the error, either pass an absolute path to the method or set the root
property in the options object

Here is the complete stack trace:
TypeError: path must be absolute or specify root to res.sendFile at ServerResponse.sendFile (/home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/response.js:441:11) at file:///home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/index.js:7:7 at Layer.handle [as handle_request] (/home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/router/layer.js:95:5) at next (/home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/router/route.js:144:13) at Route.dispatch (/home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/router/route.js:114:3) at Layer.handle [as handle_request] (/home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/router/layer.js:95:5) at /home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/router/index.js:284:15 at Function.process_params (/home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/router/index.js:346:12) at next (/home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/router/index.js:280:10) at expressInit (/home/borislav/Desktop/bobbyhadz-rest/bobbyhadz-js/node_modules/express/lib/middleware/init.js:40:5)
Here is an example of how the error occurs.
const express = require('express'); const app = express(); const port = 5000; app.get('/', (req, res) => { // โ๏ธ ERROR: res.sendFile('index.html'); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
Notice that we passed a relative path to the index.html method.
__dirname variable to solve the errorOne way to solve the error is to use the __dirname global variable.
// Using require() syntax const express = require('express'); const app = express(); const port = 5000; app.get('/', (req, res) => { // ๐๏ธ using __dirname res.sendFile(__dirname + '/index.html'); }); // ๐๏ธ /home/borislav/Desktop/bobbyhadz-js console.log(__dirname); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The __dirname global variable resolves to the directory that contains the
current file.
The example above assumes that the index.html file is located in the root
directory of your project.
Your index.html file could be as simple as the following.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <h2>bobbyhadz.com</h2> </body> </html>
If you use ES6 modules (import/export), you have to use the following syntax
instead.
// Using the ES6 Modules 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(); const port = 5000; app.get('/', (req, res) => { // ๐๏ธ using __dirname res.sendFile(__dirname + '/index.html'); }); console.log(__dirname); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The __dirname variable
is not available
when using ES modules, so we had to construct it.
root property to solve the errorYou can also use the root property of the options object to solve the error.
The res.sendFile() method
takes an optional second argument - an options object.
You can set a root property on the object to specify the root directory for
relative filenames.
// using require() syntax const express = require('express'); const app = express(); const port = 5000; app.get('/', (req, res) => { // ๐๏ธ using root property res.sendFile('index.html', {root: __dirname}); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
We set the root directory for relative filenames to the current directory and
specified index.html as the filename.
If you still get an error, you can try setting the root property to . (the
current directory).
res.sendFile('index.html', {root: '.'});
In other words, the example assumes that there is an index.html file located
in the same directory as your script.
If you use ES6 Modules, use the following syntax instead.
// using ES6 Modules 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(); const port = 5000; app.get('/', (req, res) => { // ๐๏ธ using root property res.sendFile('index.html', {root: __dirname}); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
We set the root to the current directory, so Express.js looks for an
index.js file in the current folder.
path.join() method to solve the errorAlternatively, you can use the path.join() method.
// using require() syntax const express = require('express'); const path = require('path'); const app = express(); const port = 5000; console.log(path.join(__dirname, 'index.html')); app.get('/', (req, res) => { // ๐๏ธ using path.join() res.sendFile(path.join(__dirname, 'index.html')); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The path.join() method takes 2 or more paths, joins all arguments together and
normalizes the resulting path.
Here is what the path resolves to in my case.
// ๐๏ธ /home/borislav/Desktop/bobbyhadz-js/index.html console.log(path.join(__dirname, 'index.html'));
If you use ES6 Modules, use the following syntax instead.
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(); const port = 5000; console.log(path.join(__dirname, 'index.html')); app.get('/', (req, res) => { // ๐๏ธ using path.join() res.sendFile(path.join(__dirname, 'index.html')); }); app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The arguments you pass to the path.join() method may also be relative paths.
res.sendFile(path.join(__dirname, './public/index.html'));
The example assumes that your index.js file is located in a public directory
that is contained in the current folder.
my-project โโโ public โโโ index.html โโโ index.js
If you need to go one directory up, you would use the ../ prefix.
res.sendFile(path.join(__dirname, '../public/index.html'));
The example assumes that your public folder is located one directory up.
public โโโ index.html my-project โโโ index.js
The same approach can be used if you need to go two directories up.
Simply, use a prefix of ../../
res.sendFile(path.join(__dirname, '../../public/index.html'));
The following 2 examples are equivalent.
The first example uses path.join() to resolve the error.
res.sendFile( path.join(__dirname, '../public', 'index.html') );
The second example uses the root property with path.join().
res.sendFile( 'index.html', {root: path.join(__dirname, '../public')} );
Both examples look for an index.html file, located in a public folder that
is one directory up from the current folder.
public โโโ index.html my-project โโโ index.js
You can check out more examples of using path.join() in
this section of the docs.