fix(react-router-serve): serve /.well-known files - #15340
Open
kklem0 wants to merge 1 commit into
Open
Conversation
Express 5's static middleware ignores every dot-segment path by default (send v1 dropped send v0's allowance for dot directories), so RFC 8615 well-known URIs — ACME challenges, Android's assetlinks.json, Apple's apple-app-site-association — fell through to the request handler and came back as app-rendered HTML instead of the static file. Mount the .well-known directory of the client build explicitly; other dotfiles remain hidden.
timdorr
reviewed
Jul 23, 2026
timdorr
requested changes
Jul 23, 2026
timdorr
approved these changes
Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Express 5's static middleware ignores every dot-segment path by default —
sendv1 dropped v0's allowance for dot directories when the deprecatedhiddenoption was removed. Sincereact-router-serveusesexpress.staticwith default options, any file under/.well-known/now falls through all static mounts into the request handler, which responds with app-rendered HTML (or a 404 route) instead of the file./.well-knownis the RFC 8615 home for cross-cutting platform files, so this silently breaks real deployments:/.well-known/assetlinks.json)/.well-known/apple-app-site-association)security.txt, OIDC discovery, and the rest of the well-known registryWe hit this in production: our Android
assetlinks.jsonverification received an HTML page. Related friction with.well-knownrequests reaching the router has come up before in #13516 and #15337 (dev-server side). And becausereact-router-serveintentionally exposes no options, affected apps can't work around it without ejecting to a custom Express server.Fix
Mount the client build's
.well-knowndirectory explicitly, after the existing static mounts and before the request handler:Only the
.well-knowndirectory is exposed — all other dotfiles remain hidden, matching whatsirv(used by Vite preview) does by default (lukeed/sirv#50). This restores the Express 4-era behavior for the standardized directory without reintroducing broad dot-directory serving.Testing
Added integration tests in
integration/react-router-serve-test.tsfor both the classic and RSC Framework Mode templates, run against the real spawnedreact-router-serveprocess:/.well-known/security.txt(placed inpublic/) is served with a 200/.hidden.txt) still fall through and 404All existing tests in the file pass, along with
tscfor the package andprettier --checkon touched files.