Serving static files with express.js

In this post I will be writing about serving static files in a node.js environment using express.js. The process is pretty straight forward using an express.js built in middleware for doing so (express.static). There are some additional options of interest as well thought so lets take a look.

What to know before you begin

This is a post on setting up a static server in express.js. It is not a getting started post on express.js I have another post on that here. It is also not a getting started post on javaScript in general, as well as setting up a node.js environment. I assume that you have a basic working knowledge of what is required to progress with serving static files in an express.js project, and are here to resolve some more specific issue.

I try to make it a habit to always mention what version of a framework, library, ect I am using especially if it is something advanced like express.js, as such in this post I am using express 4.16.3

A Basic static server example with express.js

For a basic example of using express.js to make a static server I made a project folder, and inside that project folder I will want a public folder with some simple hand coded assets in it. In a more advanced real word example you might use some kind of static site generator such as hexo to generate this structure.

1
2
3
4
5
$ mkdir express_static
$ cd express_static
$ npm init
$ npm install express@4.16.3 --save
$ mkdir public

For this demo I only need express installed. In this demo I am using 4.16.3, but if no major code breaking changes happen in the future, you should be able to use the latest version by dropping the @4.16.3

The public folder

index.html

So one of the most important assets to have in a public folder is the index.html file that is placed at public/index.html. It can be called something else using the index property when giving an options object to express.static, but for this basic demo I will just follow the norm. Also if nor some reason I do not want a static index a value of false can be set to the index property.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!doctype html>
<html lang="en">
<head>
<title>express static page</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrap_main">
<div class="warp_header">
<h1>Hello I am a static Page.</h1>
</div>
<div class="warp_content">
<img src="/img/happy_kitty.png">
</div>
</div>
<script src="/js/foo.js"></script>
</body>

style.css

One of the assets that will also compose my public folder is an external css file, just to have another asset in there other than just an index.html file, and haveing any style coded in page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
body{
background: #000000;
}
.wrap_main{
background: #2a2a2a;
color: #ffffff;
margin-left:auto;
margin-right:auto;
width:90%;
}
.warp_header{
text-align:center;
min-height:150px;
background:#5a5a5a;
}
/img/happy_kitty, and /js/foo.js

I also placed some additional assets that I then used in my index.html, and also to showcase that different file types can quickly and easy be used when using express.js. The foo.js file just logs foo to the console, and the happy_kitty.png file can be any image you might like when making your own demo.

The app.js file

At the root level I will of course want my app.js file that I will start with node directly or via one of the options in package.json that are started with npm. This will just create a new instance of express, and then use express.static to set the path in the project folder where static assets are.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let express = require('express'),
path = require('path'),
app = express(),
// getting port this way
port = process.env.PORT || process.argv[2] || 8080;
// using app.use to use static files in my public
// folder for the root level of the site
app.use('/', express.static('public'));
app.listen(port, function () {
console.log('app up on port: ' + port);
});

Once this is done I can start the static server.

1
$ node app.js

This will result in the public folder being the root name space of the site. So when I go to http://localhost:8080/ in my browser index.html should be what shows up.

Options

So I think I should cover some of the options that can be passed to express.static

file name extensions

The extensions array can be used to set some filename extensions in the event that a file is not found.

1
app.use('/', express.static('public',{extensions: ['htm', 'html']}));

When I do this going to localhost:8080/index is the same as localhost:8080/index.html

Custom index

By default it is expected that a file called index.html will exist at the root of the public name space. If for some reason you want a file to be called something else, or have the behavior of the root path change to something different, then the index property is what you want.

1
app.use('/', express.static('public',{index:'other.html'}));

This will use a page called other.html in place of the usual index.html which is the default that is often used. in addition to setting a single string it is possible to also give an array of strings.

1
app.use('/', express.static('public',{index:['home.html', 'index.html','other.html']}));

When this is done a file called home.html will be looked for first, in the event that is not found index.html will be used, and if for some reason that is not there other.html will be used. So in other words the index value of the array will set priority for that files superseded others when looking for a file to serve as an index.

Also if for some reason you want to disable this, and maybe do something else to generate an index server side for example it can be disabled by setting it to false.

1
2
3
4
5
6
app.use('/', express.static('public',{index:false}));
app.get('/', function(req,res){
res.send('foo');
});

When this is done I will not get any static file but the generated message ‘foo’ when going to localhost:8080/ in the browser, however I can still get to the static index I just have go directly to localhost:8080/index.html.

Conclusion

I did not cover everything when it comes to the options that can be given to express.static, in part that it because some of the options look like they might warrant a whole separate post apart from this one. So far I think that I like just working with express.js when it comes to making some kind of full stack application, although I have a simular post on this using hapi, and also there is doing this vanilla js style, by just working with the built in node.js http module. If you ejoyed this post you might want to check out my other posts on express.