Best Ways to Serve Static Files in Node.js and Express Server

Robin
Updated on November 12, 2023

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:

  1. Configure a Node.js server with Express.
  2. Create a folder to store static files.
  3. Create an Express server.
  4. 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.

Folder structure to store static files in an Express server

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.

Related Posts