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.