The express framework has a built-in method called express.static()
to server static files from your Node.js server. This method accepts 2 parameters.
The first parameter is the path of the folder where you keep your static files. The second parameter is optional where you can set some additional options.
const folderPath = path.join(__dirname, 'public')
app.use(express.static(folderPath));
You have to call the express.static()
method inside app.use()
to register it as a middleware function. Here I am serving all the files inside this public
folder as static.
You can also set multiple folders as static folders using this method.
Let's set up a complete Express server to learn more about this topic.
Also Read: Easy Ways to Download Any File From Node.js Server Using Express
Steps to Serve Static Files in Express
To serve static files from an Express and Node.js server, you have to follow a few steps. These are:
- Configure a Node.js server with Express.
- Create a folder to store static files.
- Create an Express server.
- Serve static files in Express.
Let's look into those steps in detail with some examples.
Step 1: Configure a Node.js Server with Express
First, you need to create a folder on your computer where you will store the Node.js project. I named my folder node-express-static
but you can give any name for your folder. Run the following command in your terminal:
mkdir node-express-static
Go inside your newly created folder using the cd
command.
cd node-express-static
Initialize a Node.js project with the default settings. It will create a package.json
file at the root of your project. Open this folder in a text editor, you will find a package.json
file.
This file will list all of your dependencies and dev-dependencies for this project.
npm init -y
Create a app.js
file inside the node-express-static
folder. It will be the entry file for your server.
touch app.js
Now install the express
and dotenv
packages as dependencies. Here express
is the Node.js framework and the dotenv
package is used to set environment variables for Node.js and Express.
To store environment variables, you have to create a .env
file at the root of your project. Here you can keep sensitive information like port number, API key, database credentials, etc.
npm install --save express dotenv
I will also install nodemon
as a dev-dependency. This package will restart our server in the development environment when we update any code in our project.
npm install --save-dev nodemon
Finally, I will add 2 new scripts to the package.json
file. The start
script will start our server using node
command and the dev
script will start our server using nodemon
package.
We will use the start
script in a production environment and the dev
script will be used during the time of development.
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js"
}
Step 2: Create a Folder to Store Static Files
To store our static files create a folder called public
inside the node-express-static
folder. It's not necessary that you have to name your static folder as public
. You can give any name you want.
Now in the public folder, I will create 3 new folders. These are js
, css
, and images
. In the js folder, I will store all JavaScript files that are necessary for my website. In the css
folder, I will store CSS files and the images
folder will have the image files.
If we look at the project structure, we will see that there are 4 files and 2 folders in our project. These files are:
- package.json
- package-log.json
- app.js
- .env
And 2 folders are:
- public
- node_modules
Step 3: Create an Express Server
In your app.js file, write the following code to spin up the Express server.
const { config } = require('dotenv');
const express = require('express');
const app = express();
// Load environment variables
config();
// Add routes
app.get('/', (req, res) => {
res.send('Hello World');
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server started on port ${PORT}`);
});
Here, I am loading environment variables from .env
file using the config()
function. The .env
file contains PORT=5000
that I can access with process.env.PORT
in our server.
I am also setting 5000
as a default value for the port number. If process.env.PORT
returns undefined
for any reason, our server will use 5000
as the port.
npm run dev
Now you can spin up the development server by running the dev
script. Open your browser and visit http://localhost:5000
to see the result.
Step 4: Serve Static Files in Express
Express has a built-in middleware function to set a folder as static. You have to use express.static()
function inside app.use()
function in our app.js
file.
const folderPath = path.join(__dirname, 'public')
app.use(express.static(folderPath));
With app.use()
function, we are telling Express to execute the express.static()
middleware function. It is good to use the absolute path in express.static()
function for defining a static folder.
So, import join()
function from path which is the Node.js core module. By using join()
function, I am defining an absolute path for the public
folder as the first argument in the express.static()
function.
Note: You have to set your static folder before adding any routes.
This is the complete look of our app.js
file after serving static files:
const { config } = require('dotenv');
const express = require('express');
const path = require('path');
const app = express();
// Load environment variables
config();
// Serve static files
const folderPath = path.join(__dirname, 'public')
app.use(express.static(folderPath));
// Add routes
app.get('/', (req, res) => {
res.send('Hello World');
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server started on port ${PORT}`);
});
That's it, you have successfully set up a static folder. Therefore, Express will serve everything in the public
folder as static files.
You can view any image by visiting http://localhost:5000/images/logo.png
in your browser.
You can also add a JavaScript file to your web page by specifying /js/main.js
path in the <script>
tag and a CSS file by specifying /css/style.css
path.
<script src="/js/main.js"></script>
<link rel="stylesheet" href="/css/style.css">
Adding Virtual Prefix to Static File Path
If you want to add a prefix to all of your static file paths, you can do it. You have to pass the prefix in the app.use()
function as the first argument.
const folderPath = path.join(__dirname, 'public')
app.use('/static', express.static(folderPath));
In this example, I am passing "/static" as the path prefix. Now, to access images you have to visit https://localhost:5000/static/images/logo.png
in the browser.
For JavaScript and CSS files, you also have to add /static
in front of each file path. For example, instead of using /js/main.js
you have to use /static/js/main.js
in your HTML files.
<script src="/static/js/main.js"></script>
<link rel="stylesheet" href="/static/css/style.css">
This technique is very useful when you are serving static files from multiple public folders. In this case, you set different path prefixes for the different public folders. By seeing these prefixes, you can differentiate between multiple folders.
Serve Static Files from Multiple Folders in Express
We can set up multiple static folders by using express.static()
method. In this way, we can serve different types of files from different folders.
For example, we are serving our static files like images, JavaScript, and CSS files from the public folder. But you have an option on your website that individual user can upload their profile pictures.
Now, you want to store those profile pictures in a separate folder and serve from that folder. To achieve this functionality you have to set 2 folders as static.
const publicPath = path.join(__dirname, 'public')
app.use('/public', express.static(publicPath));
const uploadsPath = path.join(__dirname, 'uploads')
app.use('/uploads', express.static(uploadsPath));
You can use path prefixes for multiple static folders. For example, I can add /public
prefix for the public folder and /uploads
for the uploads folder.
You can name these prefixes anything you want. It doesn't have to match the folder name.
When you see a path /public/images/logo.png
like this, you can easily say that this is from the public
folder. And when you see a path /uploads/images/user-1.jpg
like this, starting with /uploads
then you will know that it is from the uploads
folder.
Also Read: How to Get All Files in Directories (Recursively) with Node.js
Conclusion
Express doesn't support static file sharing by default. But you can set up your server to serve different types of files using a built-in method.
I have shown you multiple ways to serve static files using express.static()
method.
Now you will be able to easily structure your Node.js and Express server with different types of static resources.