74

I have already seen and made use of:

app.use("/css", express.static(__dirname + '/css'));

I do not wish to serve all files from the root directory, only a single file, 'ipad.htm'. What is the best way to do this with the minimum amount of code, using express.js?

James Vickers
  • 761
  • 1
  • 5
  • 7

6 Answers6

131

res.sendFile(path_to_file); is all you need; it will automatically set the correct headers and transfer the file (it internally uses the same code as express.static).

In express versions less than 4, use sendfile instead of sendFile.

Ninjakannon
  • 3,751
  • 7
  • 53
  • 76
ebohlman
  • 14,795
  • 5
  • 33
  • 35
  • 7
    I was getting 403s from this. I had to do `res.sendfile(relativePath, {root: theDirectory})` – kumar303 Mar 12 '14 at 18:22
  • 3
    if your folder is outside the one of the running JS file, I would add some detail to @kumar303 comment: you cannot put "../" in relativePath, but you can add it in theDirectory. res.sendfile(pic.png, {root: __dirname+"../../../images/"}) – Rayjax May 28 '14 at 08:46
  • Is this with `app.get('css', function (req, res) { ... })`? – Ehtesh Choudhury Nov 19 '14 at 22:10
  • 1
    I found it useful to operate relative to the project root like this: path.join(path.dirname(require.main.filename), '/relative/to/project/root/file.html') – Killroy Jun 25 '15 at 18:33
  • 6
    In Express 4.x, it looks like all-lowercase `sendfile` is deprecated in favor of `sendFile` with a capital F. What worked for me, using `uuid.js` as my example, is `app.get('js/uuid.js', function(req, res) { res.sendFile('uuid.js', {root: 'node_modules/node-uuid'}); });` – amacleod Aug 13 '15 at 19:50
  • The callback needs to be used, as shown [in the documentation](http://expressjs.com/api.html#res.sendFile), lest there be an error. – user2864740 Sep 01 '15 at 22:34
  • Express JS static is so confusing. I found it better not to use it and serve file directly as suggested by Tamlyn. – Zeni Sep 15 '18 at 06:30
  • But how do I reference the static file elsewhere in my code? – Euridice01 Mar 11 '19 at 15:42
  • For sending a file relative to the project directory, `res.sendfile(relativePath, {root: '.'})` works, at least with current versions, with no need to use `__dirname` etc. – phhu Jul 05 '22 at 08:12
17
app.use("/css/myfile.css", express.static(__dirname + '/css/myfile.css'));
Greg Bacchus
  • 2,235
  • 2
  • 23
  • 26
  • 1
    `app.use("/", express.static(__dirname + "/index.html"))` gives a 404 for me. `app.use("/", express.static(__dirname))` works. – Niklas Jul 25 '13 at 12:15
  • 2
    that is strange, it does work for me. I have app.use('/', express.static(__dirname + '/wwwroot/index.html')); I think that the order in which they app.use calls appear does make a difference. So make sure you are not mapping it to somewhere else first that is giving the 404. – Greg Bacchus Jul 31 '13 at 03:24
  • 4
    I get some weird 303 behavior that directs to the path plus a slash. Seems like static only is supposed to work on dirs. – Steven Lu Jan 29 '14 at 08:25
  • Same with serve-static also. – natario Sep 19 '16 at 13:55
  • I'm not using this for `index.html`, so can't comment on that -- but this solution works for me for the standard/filename-specified case. (express version: 4.17.1) – Venryx Oct 01 '20 at 22:04
8

If you precisely want to serve a single static file, you can use this syntax (example base on the original question, ipad.htm under root directory):

app.use('/ipad.htm', express.static(__dirname, {index: 'ipad.htm'}));

The default behaviour of express.static(dir) is that it will try to send an 'index.html' file from the required dir. The index option overrides this behaviour and lets you pick the intended file instead.

ye olde noobe
  • 1,186
  • 6
  • 12
  • 1
    Only solution that fixed annoying favicon 404 requests. `app.use('/favicon.ico', express.static('img/base', {index: 'favicon.ico'}));` – OXiGEN Dec 31 '20 at 23:46
5

I published a small library for serving single static files: https://www.npmjs.com/package/connect-static-file

npm install connect-static-file

var staticFile = require('connect-static-file'); app.use('/ipad', staticFile(__dirname + '/ipad.html'));

The main difference with express.static is that it does not care about the request url, it always serves that file if the route matches. It does not suddenly start serving an entire directory if you name your directory "ipad.html".

JoWie
  • 271
  • 3
  • 3
  • But how do I reference the static file elsewhere in my code? – Euridice01 Mar 11 '19 at 15:42
  • What do you mean by "reference"? Do you want to use the contents somewhere else in your code? If so you can just use `require('fs').readFile(pathOfTheFile, (err, data) => {...})` – JoWie Mar 12 '19 at 16:18
0

Quick example building on JoWie's answer:

npm install connect-static-file

npm install express

var express = require('express');
var staticFile = require('connect-static-file');

var path = 'pathto/myfile.txt';
var options = {};
var uri = '/';
var app = express();
var port = 3000;

app.use(uri, staticFile(path, options));

app.listen(port, () => console.log(`Serving ${path} on localhost:${port}${uri}`));
Steji
  • 580
  • 1
  • 6
  • 17
-4
 fs.createReadStream(path).pipe(res);
Pickels
  • 33,902
  • 26
  • 118
  • 178
  • 4
    You'd need to explicitly write out at least the `Content-Type` and `Content-Length` headers beforehand. – ebohlman Jul 13 '12 at 22:02