If you're using Express to deliver some type of application the chances are you'll want to send static files to a browser. When we say "static files" we're talking about HTML, client-side JavaScript, CSS files and images. That type of thing.
We're going to assume a simple bare-bones Express project as the starting point here. Really simple! A single app.js file listening for requests on port 3000, that looks like this.
var express = require('express');
var app = express();
// Define the port to run on
app.set('port', 3000);
// Listen for requests
var server = app.listen(app.get('port'), function() {
var port = server.address().port;
console.log('Magic happens on port ' + port);
});
Get the code The code for this post is available on GitHub.
Create a folder for static resources
First of all, for the sake of good organisation create a folder to hold all of the static resources. Call this folder public
.
Declare public
folder to be 'static'
When the folder is created, we need to tell Express to treat this folder as a static folder.
The skeleton for this applies an express.static
method as Express middleware via app.use
, looking like this.
app.use(express.static());
Next we need to tell the static
method the folder we want to use.
Using path
to locate a folder
To get the file path to a folder we will require
the native Node module path
, near the top of app.js.
var path = require('path');
The path
module exposes a join
method that allows us to chain together variables to create a file path. The join
method is used instead of specifying a full file path, as this avoids issues of operating systems working differently with forward slashes and backslashes.
So we'll pass path.join
into the express.static
method.
And then we'll path the folder information into path.join
. The first parameter to use is a native Node variable __dirname
which contains the file path of the current folder. The second parameter will be the name of the folder containing the static resources, in our case public
.
All together it looks like this.
app.use(express.static(path.join(__dirname, 'public')));
This will tell Express to match any routes for files found in this folder and deliver the files directly to the browser. This should be done before any other routes are defined and before the server is set up to listen.
Here's the app.js file now:
var express = require('express');
var path = require('path');
var app = express();
// Define the port to run on
app.set('port', 3000);
app.use(express.static(path.join(__dirname, 'public')));
// Listen for requests
var server = app.listen(app.get('port'), function() {
var port = server.address().port;
console.log('Magic happens on port ' + port);
});
When Express receives a request for a route it is now checking to see whether such a file path exists in the static directory we defined. If it does it delivers this directly to the browser with no need for us to add in any routes.
Sending HTML files
To try this out create a simple HTML file in the public
folder called index.html
. Something like this will be fine.
<!DOCTYPE html>
<html>
<head>
<title>MEAN is best</title>
</head>
<body>
<h1>Express FTW!</h1>
</body>
</html>
When this is saved, open the folder containing app.js in the command line run node app.js
to start the application. Then open a browser and head to http://localhost:3000/index.html
to check it out.
Default files for directories
As the file is called index.html
- like with many webservers - Express will look for this if the filename is omitted, so we can also see the homepage at http://localhost:3000
.
Defining a subset of routes
You can define that the static files should be found under a particular folder, by specifying the name of the path before the location of the files.
To only try and match routes that start with /public
update the line to:
app.use('/public', express.static(path.join(__dirname + '/public')));
Head to http://localhost:3000/public/index.html
or http://localhost:3000/public/
this time to see the page.
We're not going to do this, as we want this index page to be served up as the homepage. So delete the /public',
addition to the code.
Other file types
Naturally this isn't limited to HTML files. You can add CSS, images and JavaScript files into the public
folder and they'll all be delivered directly to the browser when requested.
Let's start with images.
Sending images to the browser
We'll brighten up our page by adding an image - our friendly Panda Wizard.
Inside the public
folder create a sub-folder called images
and paste the image in there.
Then in the index.html
file add an img
tag to reference it, like this:
<h1>Express FTW!</h1>
<img src="/images/PandaWizard.png">
Refreshing the browser on localhost:3000
you'll now see the image below the header, like this:
Pretty simple :)
We can do a similar thing with CSS.
Using Express to send CSS files to the browser
To demonstrate sending CSS files, we'll create a file with a single CSS declaration to center everything on the page.
In the public
folder create a new folder called css
. Inside this new folder create a file called styles.css
with the following content.
body { text-align : center; }
And then update index.html to reference it.
<head>
<title>MEAN is best</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
Now reloading the page in the browser shows everything centered like this.
Finally, we'll look at client-side JavaScript.
Sending JavaScript to the browser with Express
Now we'll use JavaScript to change the content of the <h1>
tag.
Once again create a new folder inside public
, this time called javascript
. In this folder create a new file called script.js
with the following content.
var header = document.getElementsByTagName("h1")[0];
header.innerHTML = "JavaScript FTW!";
When run this simple script will change the header text from Express FTW! to JavaScript FTW!.
When the file is saved it needs to be referenced in the index.html
. Then you load the page in the browser you should see the header change, and look like this:
Summary
And there we have it; a really simple Express application serving HTML, images, CSS and JavaScript to the browser. Even better, this all happens without any complex code or routing.
Really the magic is down to using the express.static
method as a piece of middleware.
The code for this post is available on GitHub https://github.com/fullstacktraining/express-static-files - remember if you clone it you'll need to run npm install
to install the dependencies before you can start the application.