Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Static files

Static files are those the browser receives as they are, without processing on the server: CSS styles, images, fonts, client-side scripts. You do not write a route for each file: the built-in express.static() middleware serves a whole folder.

The public folder

Create a public/ folder in the project root, with a stylesheet public/css/style.css inside:

body {
  max-width: 720px;
  margin: 0 auto;
  font-family: system-ui, sans-serif;
}

Enabling it

Add one line to src/app.js before the routes:

// src/app.js
app.use(express.static('public'));

Open http://localhost:3000/css/style.css and the browser shows the file. The folder name public is not part of the address: the file public/images/logo.png is available at /images/logo.png.

Using it on a page

In HTML write addresses from the site root, starting with a slash:

<link rel="stylesheet" href="/css/style.css">
<img src="/images/logo.png" alt="Blog logo">

Then the styles and the image load on any blog page — both on /posts and on /posts/2.

An address prefix

If the files should live under a separate address, pass it as the first argument:

// src/app.js
app.use('/static', express.static('public'));

Now the styles are at /static/css/style.css, and /css/style.css no longer works.

An absolute path

The path 'public' is resolved from the folder Node.js was started in. If you start the server from another place, the files are not found. It is more reliable to build the path from the location of app.js itself:

// src/app.js
import path from 'node:path';
 
const publicDir = path.join(import.meta.dirname, '..', 'public');
app.use(express.static(publicDir));

import.meta.dirname is the folder of the current module, here src/. The two dots go one level up, to the project root.

Caching

The maxAge option lets the browser keep the files and not request them again:

// src/app.js
app.use(express.static('public', { maxAge: '1d' }));

The browser takes the files from its cache for a day. Better not to enable this during development: CSS changes would not show up at once.

Common mistake

Everything in public/ is available to anyone who knows the address. Do not put the .env file, the database, the server source code or user-uploaded documents that must stay private there. public/ is only for things you are happy to show the whole internet.

Thanks for reading!

Donate to the site — we work hard for you.