From 276c85889cebfccf0e06da72054a26fcda1e886c Mon Sep 17 00:00:00 2001 From: joaquimpeixoto Date: Wed, 27 May 2026 16:01:23 +0100 Subject: [PATCH 1/2] docs: clarify sendfile dotfiles migration --- src/content/pages/en/guide/migrating-5.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/content/pages/en/guide/migrating-5.mdx b/src/content/pages/en/guide/migrating-5.mdx index b93cec072c..c0a9581869 100644 --- a/src/content/pages/en/guide/migrating-5.mdx +++ b/src/content/pages/en/guide/migrating-5.mdx @@ -284,6 +284,8 @@ Or you can update your code manually: The `hidden` and `from` options for `res.sendFile()` are no longer supported. Use `dotfiles` and `root` instead. +The `dotfiles` option applies to hidden directories in the path as well as hidden files. For example, a file served from a path like `/tmp/.mount/app/index.html` now requires `dotfiles: 'allow'`, even though `index.html` is not a dotfile. + #### How to update ```diff From bc5855ac429c4eabbea28a92b5f8a0f12066a913 Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Sun, 21 Jun 2026 20:28:52 -0500 Subject: [PATCH 2/2] docs: update migration guide for res.sendFile() and express.static() dotfiles handling --- src/content/pages/en/guide/migrating-5.mdx | 29 +++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/content/pages/en/guide/migrating-5.mdx b/src/content/pages/en/guide/migrating-5.mdx index 00319c82d4..adb15bb2e2 100644 --- a/src/content/pages/en/guide/migrating-5.mdx +++ b/src/content/pages/en/guide/migrating-5.mdx @@ -264,7 +264,9 @@ Or you can update your code manually: The `hidden` and `from` options for `res.sendFile()` are no longer supported. Use `dotfiles` and `root` instead. -The `dotfiles` option applies to hidden directories in the path as well as hidden files. For example, a file served from a path like `/tmp/.mount/app/index.html` now requires `dotfiles: 'allow'`, even though `index.html` is not a dotfile. +The `dotfiles` option applies to hidden directories in the path as well as hidden files. For example, a file served from an absolute path like `/var/www/app/.cache/index.html` now requires `dotfiles: 'allow'`, even though `index.html` is not a dotfile. In Express 4 a hidden directory in the path was served by default; Express 5 returns `404` unless you opt in. + +This check only applies to the part of the path that `send` evaluates. When you pass a `root`, only the portion relative to `root` is checked, so a hidden directory inside `root` is unaffected. #### How to update @@ -275,12 +277,30 @@ The `dotfiles` option applies to hidden directories in the path as well as hidde }); ``` +If you serve an absolute path that contains a hidden directory, opt in with `dotfiles: 'allow'` or use `root` so the hidden segment is not part of the evaluated path: + +```diff + app.get('/build', (req, res) => { +- res.sendFile('/var/www/app/.cache/index.html'); ++ res.sendFile('/var/www/app/.cache/index.html', { dotfiles: 'allow' }); ++ // or: res.sendFile('index.html', { root: '/var/www/app/.cache' }); + }); +``` + ### express.static() options The `hidden` and `from` options for `express.static()` are no longer supported. Use `dotfiles` and `root` instead. Note that `from` was never documented in the API but was accepted as an alias for `root`. The default value of `dotfiles` is now `"ignore"`. +The `dotfiles` check now also applies to hidden **directories** in the request path, not just hidden files. A request like `GET /.well-known/acme-challenge/...` that was served by default in Express 4 now returns `404` unless you set `dotfiles: 'allow'`. This only affects the part of the path relative to the configured `root`; a hidden directory in `root` itself is unaffected. + #### How to update +You can automatically update your code by running the following command: + + + +Or you can update your code manually: + ```diff const express = require('express'); const app = express(); @@ -289,6 +309,13 @@ The `hidden` and `from` options for `express.static()` are no longer supported. +app.use(express.static('public', { dotfiles: 'allow' })); ``` +If you rely on serving a hidden directory such as `.well-known` (for example, ACME/Let's Encrypt challenges), opt in explicitly. This is needed even if you never used the `hidden` option: + +```diff +-app.use(express.static('public')); ++app.use(express.static('public', { dotfiles: 'allow' })); +``` + ### router.param(fn) The `router.param(fn)` signature was used for modifying the behavior of the `router.param(name, fn)` function. It has been deprecated since v4.11.0, and Express 5 no longer supports it at all.