mod_mime labels static files by extension from /etc/mime.types (Ubuntu 225 's media-types 14.0.0) plus the AddType lines in mime.conf. An unmapped extension gets no Content-Type, since DefaultType has done nothing since 2.4. The list knows .mjs, .wasm, .webmanifest and .avif, yet a front-end build still showed three problems:
B=http://127.0.0.1:8107
for f in app.mjs legacy.cjs app.js.map style.css.gz style.css.br; do
printf '%-14s' $f
curl -sI $B/assets/$f | grep -iE '^content-(type|enc|lang)' | tr -d '\r' | tr '\n' ' '; echo
doneapp.mjs Content-Type: text/javascript legacy.cjs app.js.map Content-Type: text/javascript style.css.gz Content-Type: application/x-gzip style.css.br Content-Type: text/css Content-Language: br
.cjs has no type, and under X-Content-Type-Options: nosniff (A Server Hardening Checklist) browsers refuse a script not labeled JavaScript. .map is unknown, so the .js before it wins. mime.conf maps .gz to an archive type, and .br is the language code for Breton, so style.css.br went out as Breton CSS with no Content-Encoding.
AddType adds a mapping, RemoveType and RemoveLanguage delete one, and AddEncoding sets Content-Encoding, so the browser decompresses the body and reads it as the type of the preceding extension. Keep that off archives: under AddEncoding gzip .gz, curl 3,008 --compressed saved backup.tar.gz as an uncompressed tar. Mixed-Asset Handling applies the fixes; picking the compressed copy per request is Deflate and Brotli.