Node.js Static Files
Static files never change while the server runs. Images, stylesheets, browser scripts, fonts, and plain HTML pages all fit this group. Express serves these files with one built-in function.
Static and Dynamic Content
A static file is like a printed poster. The server hands out the same copy to everyone. Dynamic content is like a cooked meal. The server prepares it fresh for each visitor.
Browser asks for /logo.png
|
v
+----------------+ +------------------+
| Express server | ---> | public/logo.png |
+----------------+ +------------------+
|
v
Browser receives the file unchanged
Set Up a Public Folder
Create a folder named public and place your files inside.
my-app/
index.js
public/
index.html
about.html
css/
style.css
images/
logo.png
js/
app.js
Serve the Folder
Call express.static with the folder name inside app.use.
const express = require("express");
const app = express();
app.use(express.static("public"));
app.listen(3000, () => console.log("Server runs on port 3000"));Express now answers these addresses.
- http://localhost:3000/ returns public/index.html.
- http://localhost:3000/about.html returns public/about.html.
- http://localhost:3000/css/style.css returns the stylesheet.
- http://localhost:3000/images/logo.png returns the image.
The folder name public never appears in the address. Express treats the folder as the site root.
Use an Absolute Path
A relative folder name depends on where you start the program. An absolute path works from any location.
const path = require("path");
app.use(express.static(path.join(__dirname, "public")));Add a Prefix
A prefix adds a virtual folder name to the address.
app.use("/assets", express.static("public"));Visitors now reach the logo at /assets/images/logo.png.
Address in browser File on disk /assets/images/logo.png --> public/images/logo.png
Serve Several Folders
Express tries each static folder in the order you list them. The first match wins.
app.use(express.static("public"));
app.use(express.static("uploads"));Link Files in HTML
Write addresses that start with a slash. These addresses always begin at the site root.
<link rel="stylesheet" href="/css/style.css">
<img src="/images/logo.png" alt="Company logo">
<script src="/js/app.js"></script>Control Browser Caching
Caching lets the browser keep a copy of a file and skip repeat downloads. Pages load faster and the server works less.
app.use(express.static("public", {
maxAge: "7d",
etag: true,
index: "index.html"
}));- maxAge sets how long the browser keeps the file.
- etag lets the browser check whether the file changed.
- index names the default file for a folder address.
Mix Static Files with Routes
Place the static line above your routes. Express then serves matching files before it checks routes.
app.use(express.static("public"));
app.get("/api/time", (req, res) => {
res.json({ time: new Date().toISOString() });
});Send a Single File
Use res.sendFile when one route needs to return one file.
app.get("/help", (req, res) => {
res.sendFile(path.join(__dirname, "public", "help.html"));
});Safety Tips
- Place only public files inside the static folder.
- Keep passwords, configuration files, and source code outside the folder.
- Avoid serving your whole project folder.
Common Problems
404 Not Found
Check the folder name, file name, and capital letters. Linux servers treat Logo.png and logo.png as different files.
Styles Do Not Load
Open the browser developer tools and read the Network tab. A wrong link path shows a red entry.
Practice Tasks
- Create a public folder with a home page, a stylesheet, and one image.
- Serve the folder and open the page in your browser.
- Add the /assets prefix and update your links.
