267

I want to serve index.html and /media subdirectory as static files. The index file should be served both at /index.html and / URLs.

I have

web_server.use("/media", express.static(__dirname + '/media'));
web_server.use("/", express.static(__dirname));

but the second line apparently serves the entire __dirname, including all files in it (not just index.html and media), which I don't want.

I also tried

web_server.use("/", express.static(__dirname + '/index.html'));

but accessing the base URL / then leads to a request to web_server/index.html/index.html (double index.html component), which of course fails.

Any ideas?


By the way, I could find absolutely no documentation in Express on this topic (static() + its params)... frustrating. A doc link is also welcome.

user124114
  • 8,372
  • 11
  • 41
  • 63
  • 6
    As of express 4.x, `express.static()` is handled by `serve-static` package middleware. you can find its docs at https://www.npmjs.com/package/serve-static or https://github.com/expressjs/serve-static. – Anm Jan 27 '15 at 07:51
  • can someone please explain what "server as static files" means? – Abhi Jul 30 '16 at 09:18
  • @iLiveInAPineappleUnderTheSea In a dynamic web application, such as when using Express, the page content is created - or generated - by the application. On the other hand, static files are served (mostly) unmodified from a static directory hierarchy. For example, while the pages may change, the image files, CSS files, and Javascript files do not. – Philip Callender Aug 09 '16 at 04:03
  • check below link http://only4ututorials.blogspot.com/2017/05/how-to-serve-static-file-in-express-js.html – Dexter May 22 '17 at 15:45
  • Here I made a video for similar purpose. It uses express and serve-index to make complete file sharing solution over the lan. https://youtu.be/4S6doMsaT78 – Yogesh Jog Dec 06 '20 at 17:34

12 Answers12

223

If you have this setup

/app
   /public/index.html
   /media

Then this should get what you wanted

var express = require('express');
//var server = express.createServer();
// express.createServer()  is deprecated. 
var server = express(); // better instead
server.configure(function(){
  server.use('/media', express.static(__dirname + '/media'));
  server.use(express.static(__dirname + '/public'));
});

server.listen(3000);

The trick is leaving this line as last fallback

server.use(express.static(__dirname + '/public'));

As for documentation, since Express uses connect middleware, I found it easier to just look at the connect source code directly.

For example this line shows that index.html is supported https://github.com/senchalabs/connect/blob/2.3.3/lib/middleware/static.js#L140

TylerH
  • 20,799
  • 66
  • 75
  • 101
250R
  • 35,945
  • 7
  • 33
  • 25
157

In the newest version of express the "createServer" is deprecated. This example works for me:

var express = require('express');
var app = express();
var path = require('path');

//app.use(express.static(__dirname)); // Current directory is root
app.use(express.static(path.join(__dirname, 'public'))); //  "public" off of current is root

app.listen(80);
console.log('Listening on port 80');
ChrisCantrell
  • 3,833
  • 1
  • 22
  • 14
118

express.static() expects the first parameter to be a path of a directory, not a filename. I would suggest creating another subdirectory to contain your index.html and use that.

Serving static files in Express documentation, or more detailed serve-static documentation, including the default behavior of serving index.html:

By default this module will send “index.html” files in response to a request on a directory. To disable this set false or to supply a new index pass a string or an array in preferred order.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
abe
  • 1,549
  • 1
  • 11
  • 9
  • 7
    And just for information, it will serve up index.html by default in that other directory – TheSteve0 Feb 12 '14 at 02:55
  • If there is only ONE parameter - then `express.static` expects that one parameter to be path.... – Seti Dec 16 '16 at 08:21
  • Side question, how do you for instance make "/" render "/welcome.html" from the public folder? Right now I use "res.sendFile" and load the file from the server (so not using the fact that it's a public file), but maybe a rewrite/redirect could be more appropriate? – Eric Burel Sep 02 '22 at 08:28
59

res.sendFile & express.static both will work for this

var express = require('express');
var app = express();
var path = require('path');
var public = path.join(__dirname, 'public');

// viewed at http://localhost:8080
app.get('/', function(req, res) {
    res.sendFile(path.join(public, 'index.html'));
});

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

app.listen(8080);

Where public is the folder in which the client side code is

As suggested by @ATOzTOA and clarified by @Vozzie, path.join takes the paths to join as arguments, the + passes a single argument to path.

Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219
10
const path = require('path');

const express = require('express');

const app = new express();
app.use(express.static('/media'));

app.get('/', (req, res) => {
    res.sendFile(path.resolve(__dirname, 'media/page/', 'index.html'));
});

app.listen(4000, () => {
    console.log('App listening on port 4000')
})
Rajkumar
  • 1,017
  • 9
  • 12
7

If you have a complicated folder structure, such as

- application
     - assets
         - images
             - profile.jpg
     - web
     - server
        - index.js

If you want to serve assets/images from index.js

app.use('/images', express.static(path.join(__dirname, '..', 'assets', 'images')))

To view from your browser

http://localhost:4000/images/profile.jpg

If you need more clarification comment, I'll elaborate.

Saahithyan Vigneswaran
  • 6,841
  • 3
  • 35
  • 45
  • my assets folder contain css , js , images . How can I get them by using this method . note : I have also same folder structure . @SaahityanVigneswaran –  Feb 21 '22 at 12:36
5

use below inside your app.js

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

(folderName is folder which has files) - remember these assets are accessed direct through server path (i.e. http://localhost:3000/abc.png (where as abc.png is inside folderName folder)

Pravin Bansal
  • 4,315
  • 1
  • 28
  • 19
3

npm install serve-index

var express    = require('express')
var serveIndex = require('serve-index')
var path = require('path')
var serveStatic = require('serve-static')
var app = express()
var port = process.env.PORT || 3000;
/**for files */
app.use(serveStatic(path.join(__dirname, 'public')));
/**for directory */
app.use('/', express.static('public'), serveIndex('public', {'icons': true}))

// Listen
app.listen(port,  function () {
  console.log('listening on port:',+ port );
})
Rejayi CS
  • 1,034
  • 1
  • 10
  • 22
1

I would add something that is on the express docs, and it's sometimes misread in tutorials or others.

app.use(mountpoint, middleware) 

mountpoint is a virtual path, it is not in the filesystem (even if it actually exists). The mountpoint for the middleware is the app.js folder.

Now

app.use('/static', express.static('public')`

will send files with path /static/hell/meow/a.js to /public/hell/meow/a.js

Minsky
  • 2,277
  • 10
  • 19
0

This is the error in my case when I provide links to HTML files.

before:

<link rel="stylesheet" href="/public/style.css">

After:

<link rel="stylesheet" href="/style.css">

I just removed the static directory path from the link and the error is gone. This solves my error one thing more don't forget to put this line where you are creating the server.

var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public')));
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
0

You can make your own function to do it like this:


const static = (root = "") => app.get(/./, (req, res) => res.sendFile(__dirname + root + req.url));

You can also do it with express like this:


app.use('/', express.static(public));
-3

You can achieve this by just passing the second parameter express.static() method to specify index files in the folder

const express = require('express');
const app = new express();
app.use(express.static('/media'), { index: 'whatever.html' })