Fix SPA dynamic route handling with proper HTTP status codes#6469
Draft
Fix SPA dynamic route handling with proper HTTP status codes#6469
Conversation
Subclass Starlette's StaticFiles to consult app.router on a 404. When the path matches a defined dynamic route, rewrite the status to 200 so the SPA shell renders correctly with a proper status code. True misses still return 404. Asset extensions skip the route check to avoid CPU overhead. Refs #6463
…namic routes Move ReflexStaticFiles to module level (drop the lazy __getattr__ now that starlette is imported at the top of exec.py). Have the compiler emit a routes_manifest.json next to stateful_pages.json listing every defined route pattern; get_frontend_mount falls back to loading it when no resolver is passed in. This lets the standalone frontend prod app distinguish dynamic routes from true 404s without an App instance. Also add tests covering frontend_path prefix mounting and manifest load/missing/invalid paths. Refs #6463
Move ReflexStaticFiles, _is_html_navigation, _load_routes_manifest, get_frontend_mount, and _frontend_prod_app out of reflex/utils/exec.py into a dedicated reflex/utils/frontend.py module. Update the runner target string and the call site in app.py. Hoist the prerequisites import in the renamed test_frontend.py instead of re-importing it inside each test.
Merging this PR will not alter performance
Comparing Footnotes
|
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.
Type of change
Description
This PR fixes how the frontend static file server handles Single Page Application (SPA) dynamic routes. Previously, requests to valid dynamic routes (e.g.,
/blog/[slug]) that didn't have prerendered files would incorrectly return HTTP 404, even though the SPA shell was being served.Key Changes:
New
reflex/utils/frontend.pymodule: Extracted and enhanced frontend serving logic with:ReflexStaticFiles: A custom StarletteStaticFilessubclass that intelligently distinguishes between:_is_html_navigation(): Helper to identify navigation requests vs. static assets based on file extensions_load_routes_manifest(): Loads route patterns from disk for the standalone frontend serverget_frontend_mount(): Creates a properly configured Starlette Mount for frontend servingRoutes manifest system:
_write_routes_manifest()toreflex/app.pyto persist all defined routes at compile timeROUTES_MANIFESTconstant to track the manifest file locationAppinstanceIntegration updates:
reflex/app.pyto passapp.routertoget_frontend_mount()for dev serverreflex/compiler/compiler.pyto write the routes manifest during compilationreflex/utils/exec.pyto the newreflex/utils/frontend.pyComprehensive test coverage: Added 11 unit tests covering:
Why This Matters
This fixes a critical issue where dynamic routes in Reflex apps would appear broken when accessed directly (e.g., via URL bar or external links), even though the SPA could navigate to them internally. The fix ensures proper HTTP semantics while maintaining SPA functionality.
Testing
tests/units/utils/test_frontend.pyhttps://claude.ai/code/session_01S2Du3ZAXqyLPfvCYCSPCRU