nix/hive-gateway: stop SPA fallback from masking missing /matrix/ assets (#643)

iris's diagnosis on #643 (mara's fluffychat-web login attempt): the gateway's
`/matrix/` location used

    try_files $uri $uri/ /matrix/index.html;

which silently returned `index.html` (Content-Type: text/html, status 200) for
ANY missing path under `/matrix/`, including static assets like
`native_executor.js`. flutter's bootstrap requested that JS file, got HTML back,
failed to load the JS runtime, and the page rendered blank without any visible
error in the browser console.

(Confirmed root cause for the missing file itself: the upstream `fluffychat-web`
dist in nixpkgs ships `native_executor.dart` but no compiled `native_executor.js`,
even though `main.dart.js` references the latter. That's a separate
fluffychat-web packaging issue — tracked separately; this PR fixes only the
gateway-side masking that hides such failures.)

Replaces the inline `try_files` fallback with a named-location fallback that
distinguishes between route-shaped URIs (no extension) and asset-shaped URIs
(any `.<ext>` suffix):

    location /matrix/ {
      alias <pkg>/;
      try_files $uri $uri/ @matrix_spa_fallback;
    }

    location @matrix_spa_fallback {
      if ($uri ~ "\.[A-Za-z0-9]+$") {
        return 404;
      }
      rewrite ^ /matrix/index.html last;
    }

Routes still fall back to `index.html` so SPA client-side routing keeps
working; missing assets now surface a real 404 so flutter (and the operator's
devtools) can see the failure.

Verified the rendered nginx location attr via
`nix eval .#nixosConfigurations.* .... locations."@matrix_spa_fallback".extraConfig`.
This commit is contained in:
atlas 2026-05-31 01:27:25 +02:00 committed by Mara
commit 6d886da19f

View file

@ -164,7 +164,29 @@ in
"/matrix/" = {
alias = "${matrixCfg.gui.package}/";
extraConfig = ''
try_files $uri $uri/ /matrix/index.html;
try_files $uri $uri/ @matrix_spa_fallback;
'';
};
# SPA fallback (iris/#643). The naive
# `try_files $uri $uri/ /matrix/index.html;` shape
# silently masked missing static assets — flutter's
# bootstrap requesting e.g. `/matrix/native_executor.js`
# got `index.html` (Content-Type: text/html, status
# 200) when the file was absent from the dist, so
# the JS runtime never loaded and `/matrix/` rendered
# blank without any visible error.
#
# Asset-shaped URIs (anything with a `.<ext>` segment)
# get an explicit 404 so the SPA + browser see the
# missing-asset error cleanly. Only route-shaped URIs
# (no extension) fall through to index.html for SPA
# client-side routing.
"@matrix_spa_fallback" = {
extraConfig = ''
if ($uri ~ "\.[A-Za-z0-9]+$") {
return 404;
}
rewrite ^ /matrix/index.html last;
'';
};
}