Node and Express - Serve Static Files
Learn everything about Express in this Node and Express tutorial series. This article goes in depth on serving static files with Express.
Table of Contents 📖
- What is a Static File?
- Where to Serve Static Files From
- Enabling Express to Serve Static Files
- What is express.static()?
- Serving a Static File
- Accessing a Static File with the URL
- Multiple Static Directories
- Virtual Prefix
- Specifying an Absolute Path for Static Content
- What is __dirname? What is path.join()?
- Summary
What is a Static File?
A static file is a file whose content is exactly the same for each and every request. Static files are typically CSS files, images, scripts, and other files that are sent to the browser when requested without needing to be generated by the server. For example, the style of a website could be dependent on some CSS files whose content doesn't change. Therefore, when the website is requested from a browser, the CSS files are static and served up as is.
Where to Serve Static Files From
By convention, static files are often stored in a folder titled public. So, lets create a public folder in the top level of our application.
Enabling Express to Serve Static Files
To allow our Express application to serve static files, we have to use a built-in middleware. Place the following with our other app.use declarations in our top level index.js.
app.use(express.static('./public'));
Now, Express will look for all static files inside the public directory.
What is express.static()?
Express.static is a middleware for serving static content from an Express application. It takes a folder location as an argument which tells our Express application where the static content is located. Here, it is the folder public. As we have seen previously, app.use is used to add global middleware. We add express.static() as global middleware because for every route accessed we want to be able to serve up static content.
Serving a Static File
To demonstrate serving static content, lets add an image to our public folder and then display it in our profile.pug file.
doctype html
html
head
title User Profile
body
img(src="/wittcode-logo.png")
h1 #{username}'s Profile
Here, we are displaying the image titled wittcode-logo.png inside our profile.pug file. Note that as we have told Express our static files are located inside the public folder, everything we pass is relative to the public folder. In other words, when we pass /wittcode-logo.png it is essentially public/wittcode-logo.png.
Accessing a Static File with the URL
Anything placed inside our public folder can also be accessed with a url. For example, to access wittcode-logo.png, we would type in the browser localhost:1234/wittcode-logo.png. The static content will then be retrieved.
Of course, this could be done with other files. For example, if we had a soccer.js file in our public directory we could access it by localhost:1234/soccer.js. Also, note that the name of the static directory (public) is omitted. This is because Express looks up the files relative to the static directory.
Multiple Static Directories
We can have more than one static directory with Express. In other words, we can have another directory besides public to house our static content. To do this, we just call app.use(express.static()) again and pass it another directory.
app.use(express.static('./public-2'));
We could then create a folder called public-2 and place static content in there. Now, if we look up a static file, Express will first look in the static directory listed first.
app.use(express.static('./public'));
app.use(express.static('./public-2'));
So here, if we were looking for wittcode-logo.png, Express would first look in the public folder. If wittcode-logo.png could not be found, it would then look inside the public-2 folder.
Virtual Prefix
When we were searching for our static files in the url bar, we were excluding the name of the directory that houses our static content. For example, we searched for localhost:1234/wittcode-logo.png as opposed to localhost:1234/public/wittcode-logo.png.
However, we can append a virtual prefix if we want. The following code will place the prefix "static" before the name of our static content.
app.use('/static', express.static('./public'));
Now, to find our wittcode-logo.png we would have to type the url localhost:1234/static/wittcode-logo.png.
Specifying an Absolute Path for Static Content
Throughout this article we have been specifying the path to our static content folder relatively. For example, we were just specifying ./public. However, the path we provide to express.static is relative to the directory where we launch the node process. Therefore, specifying a relative path could cause some issues if we ran our express application from a different directory. To get around this, we can specify the absolute path to the directory that we want to serve. An absolute path is essentially all the details needed to locate a resource, there are no shortcuts.
So, at the top of our index.js file, we will first require the path module. The path module is a global module that makes interacting with file paths simpler.
const path = require('path');
Now lets use the path.join and __dirname to specify the absolute path to our file.
app.use('/static', express.static(path.join(__dirname, 'public')));
What is __dirname? What is path.join()?
__dirname is a Node environment variable that tells us the absolute path to the directory containing the file. Path.join joins the specified path to the second argument. These two together will provide the absolute path on our machine to the public folder.
Summary
But there we have it! We can now serve static content without Express application. If this article was helpful, please consider donating by using the link at the top of the page, sharing this article, and subscribing to my YouTube channel WittCode.