165

If I do a

res.sendfile('public/index1.html'); 

then I get a server console warning

express deprecated res.sendfile: Use res.sendFile instead

but it works fine on the client side.

But when I change it to

res.sendFile('public/index1.html');

I get an error

TypeError: path must be absolute or specify root to res.sendFile

and index1.html is not rendered.

I am unable to figure out what the absolute path is. I have public directory at the same level as server.js. I am doing the res.sendFile from with server.js. I have also declared app.use(express.static(path.join(__dirname, 'public')));

Adding my directory structure:

/Users/sj/test/
....app/
........models/
....public/
........index1.html

What is the absolute path to be specified here ?

I'm using Express 4.x.

nbro
  • 15,395
  • 32
  • 113
  • 196
Kaya Toast
  • 5,267
  • 8
  • 35
  • 59
  • If you're using the `express.static` middleware to serve your public directory, why do you need `res.sendFile` to send `public/index1.html`? – Mike S Aug 23 '14 at 15:51
  • 2
    I'm calling `res.sendFile` from within `app.get('/', function(req, res){res.sendFile("...")})` to send it on demand. – Kaya Toast Aug 23 '14 at 16:17

13 Answers13

360

The express.static middleware is separate from res.sendFile, so initializing it with an absolute path to your public directory won't do anything to res.sendFile. You need to use an absolute path directly with res.sendFile. There are two simple ways to do it:

  1. res.sendFile(path.join(__dirname, '../public', 'index1.html'));
  2. res.sendFile('index1.html', { root: path.join(__dirname, '../public') });

Note: __dirname returns the directory that the currently executing script is in. In your case, it looks like server.js is in app/. So, to get to public, you'll need back out one level first: ../public/index1.html.

Note: path is a built-in module that needs to be required for the above code to work: var path = require('path');

Mike S
  • 41,895
  • 11
  • 89
  • 84
  • 27
    `res.sendFile('../public/index.html', {root: __dirname});` also works and it's shorter – Fabien Sa Aug 22 '15 at 20:24
  • Working with express and webstorm ide: got no error in `console.log(path.join(__dirname, '../public', 'index.html'));` but `res.sendFile(path.join(__dirname, '../public', 'index.html'));` work only with `var path = require('path');` – Quake1TF Apr 19 '17 at 14:53
  • Is there no way to pre-define the absolute path so it can be used in sendFile ? – eran otzap May 11 '18 at 20:27
  • 4
    `res.sendFile('../public/index.html', {root: __dirname});` doesn't work (anymore), as it returns 403 Forbidden due to going above the root. Do `res.sendFile('public/index.html', {root: path.dirname(__dirname)});` instead. – Trevor Robinson Oct 30 '18 at 09:03
59

Just try this instead:

res.sendFile('public/index1.html' , { root : __dirname});

This worked for me. the root:__dirname will take the address where server.js is in the above example and then to get to the index1.html ( in this case) the returned path is to get to the directory where public folder is.

12

An alternative that hasn't been listed yet that worked for me is simply using path.resolve with either separate strings or just one with the whole path:

// comma separated
app.get('/', function(req, res) {
    res.sendFile( path.resolve('src', 'app', 'index.html') );
});

Or

// just one string with the path
app.get('/', function(req, res) {
    res.sendFile( path.resolve('src/app/index.html') );
});

(Node v6.10.0)

Idea sourced from https://stackoverflow.com/a/14594282/6189078

Phil Gibbins
  • 492
  • 5
  • 13
10
res.sendFile( __dirname + "/public/" + "index1.html" );

where __dirname will manage the name of the directory that the currently executing script ( server.js ) resides in.

SOuřaan Gřg
  • 399
  • 4
  • 16
9

Based on the other answers, this is a simple example of how to accomplish the most common requirement:

const app = express()
app.use(express.static('public')) // relative path of client-side code
app.get('*', function(req, res) {
    res.sendFile('index.html', { root: __dirname })
})
app.listen(process.env.PORT)

This also doubles as a simple way to respond with index.html on every request, because I'm using a star * to catch all files that weren't found in your static (public) directory; which is the most common use case for web-apps. Change to / to return the index only in the root path.

Jaime Gómez
  • 6,961
  • 3
  • 40
  • 41
6

process.cwd() returns the absolute path of your project.

Then :

res.sendFile( `${process.cwd()}/public/index1.html` );
Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
5

I tried this and it worked.

app.get('/', function (req, res) {
    res.sendFile('public/index.html', { root: __dirname });
});
boms
  • 91
  • 1
  • 11
3

you can use send instead of sendFile so you wont face with error! this works will help you!

fs.readFile('public/index1.html',(err,data)=>{
if(err){
  consol.log(err);
}else {
res.setHeader('Content-Type', 'application/pdf');

for telling browser that your response is type of PDF

res.setHeader('Content-Disposition', 'attachment; filename='your_file_name_for_client.pdf');

if you want that file open immediately on the same page after user download it.write 'inline' instead attachment in above code.

res.send(data)
Jasurbek
  • 2,946
  • 3
  • 20
  • 37
Aref.T
  • 41
  • 5
2

Another way to do this by writing less code.

app.use(express.static('public'));

app.get('/', function(req, res) {
   res.sendFile('index.html');
});
Tim Anishere
  • 796
  • 6
  • 7
2

If you want to set this up once and use it everywhere, just configure your own middleware. When you are setting up your app, use the following to define a new function on the response object:

app.use((req, res, next) => {
  res.show = (name) => {
    res.sendFile(`/public/${name}`, {root: __dirname});
  };
  next();
});

Then use it as follows:

app.get('/demo', (req, res) => {
  res.show("index1.html");
});
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
danp
  • 71
  • 2
1

Worked for me:

res.sendFile("./public/filename.ext", { root: "./" });
Pedro Rabbi
  • 193
  • 1
  • 12
0

I use Node.Js and had the same problem... I solved just adding a '/' in the beggining of every script and link to an css static file.

Before:

<link rel="stylesheet" href="assets/css/bootstrap/bootstrap.min.css">

After:

<link rel="stylesheet" href="/assets/css/bootstrap/bootstrap.min.css">
Jackson D
  • 130
  • 6
0

The following worked for me

res.sendFile(path.resolve(__dirname,'./path_to_file_from_current_directory'));
VB11
  • 27
  • 1
  • 5