6

NOTE : This is NOT a duplicate question, I've already tried other answers to similar questions.

I'm trying to render html files (Angular) but I'm having an issue. This works.

app.get('/randomlink', function(req, res) {
    res.sendFile( __dirname + "/views/" + "test2.html" );
});

But I don't want to copy and paste dirname thingy over and over, so I tried this in order to not to be repetitive with urls:

app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'views')));

app.get('/randomlink', function(req, res) {
     res.sendFile('test2.html'); // test2.html exists in the views folder
 });

Here's the error.

My express version is 4.13

path must be absolute or specify root to res.sendFile

salep
  • 1,332
  • 9
  • 44
  • 93

5 Answers5

14

If you look into the express code for sendFile, then it checks for this condition:

if (!opts.root && !isAbsolute(path)) {
    throw new TypeError('path must be absolute or specify root to res.sendFile');
}

So You must need to pass Absolute path or relative path with providing root key.

res.sendFile('test2.html', { root: '/home/xyz/code/'});

And if you want to use relative path and then you can make use path.resolve to make it absolute path.

var path = require('path');
res.sendFile(path.resolve('test2.html'));
Hiren S.
  • 2,793
  • 15
  • 25
  • This was what I needed. I had to go back a step back in the directory with a `./path` and the `__dirname` wasn't offering that flexibilty, or maybe I wasn't doing it right, but path is gorgeos! – KhoPhi Apr 22 '16 at 00:37
  • But now the `root` option has to be absolute! In my case the node file is in a subfolder, it needs to serve a file that is one directory higher. – Kokodoko Jul 24 '19 at 18:26
6

You can't go against official documentation of res.sendFile()

Unless the root option is set in the options object, path must be an absolute path to the file.

But I understand that you don't want to copy smth like __dirname every time, and so for your purpose I think you can define your own middleware:

function sendViewMiddleware(req, res, next) {
    res.sendView = function(view) {
        return res.sendFile(__dirname + "/views/" + view);
    }
    next();
}

After that you can easily use this middleware like this

app.use(sendViewMiddleware);

app.get('/randomlink', function(req, res) {
    res.sendView('test2.html');
});
Rashad Ibrahimov
  • 3,279
  • 2
  • 18
  • 39
1

Easiest way is to specify the root:

res.sendFile('index.html', { root: __dirname });
A-Sharabiani
  • 17,750
  • 17
  • 113
  • 128
0

I was facing the same problem then i solved my issue as follows.

const path = require("path")
app.get('/', (req, res)=>{
    res.sendFile(path.resolve("index.html"))
}

Good Luck

crispengari
  • 7,901
  • 7
  • 45
  • 53
0

the issue happened to me when I was providing subpaths. I set static path and had this route:

const public = path.join(__dirname, "..", "live", "public");

app.get("*", (_, res) => {
  res.sendFile("index.html");
});

Visiting "/" path worked but "/anyOtherPath" did not work. So I change the route:

app.get("*", (_, res) => {
  res.sendFile(public + "/index.html");
});
Yilmaz
  • 35,338
  • 10
  • 157
  • 202