Skip to content

Commit b3ac558

Browse files
committed
refactor: enhance static file path resolution with SPA fallback
1 parent 0df7014 commit b3ac558

2 files changed

Lines changed: 16 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* Fix `find_platform_image` selecting incompatible icon formats (e.g. `.icns` on Windows) by ranking glob results per target platform ([#6381](https://github.com/flet-dev/flet/pull/6381)) by @HG-ha.
2020
* Fix `Page.show_drawer()`, `close_drawer()`, and root/top view accessors (`appbar`, `drawer`, `navigation_bar`, `controls`, ...) failing with `TypeError` under `Page.render_views()` by unwrapping component-wrapped views and normalizing single-view returns ([#6413](https://github.com/flet-dev/flet/issues/6413), [#6414](https://github.com/flet-dev/flet/pull/6414)) by @FeodorFitsner.
2121
* Fix `auto_scroll` on scrollable controls silently doing nothing unless `scroll` was also explicitly set ([#6397](https://github.com/flet-dev/flet/issues/6397), [#6404](https://github.com/flet-dev/flet/pull/6404)) by @ndonkoHenri.
22+
* Fix Flet web returning `index.html` with a `200 OK` for missing asset files; requests for paths with a file extension other than `.html` now return a proper `404`, while route-like paths still fall back to `index.html` for SPA routing ([#6425](https://github.com/flet-dev/flet/pull/6425)) by @ndonkoHenri.
2223

2324
### Other changes
2425

sdk/python/packages/flet-web/src/flet_web/fastapi/flet_static_files.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,19 +91,29 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
9191
await super().__call__(scope, receive, send)
9292

9393
def lookup_path(self, path: str) -> tuple[str, Optional[os.stat_result]]:
94-
"""Returns the index file when no match is found.
94+
"""Resolve a static file path, with SPA fallback for client-side routes.
95+
96+
Route-like paths (no extension, or `.html`) that don't match a file
97+
fall back to `index.html` so the Flutter client can handle routing.
98+
Asset-like paths (any other extension) resolve to a real `404`.
9599
96100
Args:
97-
path (str): Resource path.
101+
path: Requested path, relative to the mounted static root
102+
(e.g. `"about"`, `"sample.json"`).
98103
99104
Returns:
100-
[tuple[str, os.stat_result]]: Always returns a full path and stat result.
105+
A `(full_path, stat_result)` tuple. When `stat_result` is
106+
`None`, Starlette responds with `404`.
101107
"""
102108
logger.debug(f"StaticFiles.lookup_path: {self.__app_mount_path} {path}")
103109
full_path, stat_result = super().lookup_path(path)
104110

105-
# if a file cannot be found
106-
if stat_result is None:
111+
if stat_result is not None:
112+
return full_path, stat_result
113+
114+
# Not found: SPA fallback only for route-like paths.
115+
ext = os.path.splitext(path)[1].lower()
116+
if ext == "" or ext == ".html":
107117
return super().lookup_path(self.index[0])
108118

109119
return full_path, stat_result

0 commit comments

Comments
 (0)