I'm serving React app from FastAPI by
mounting
app.mount("/static", StaticFiles(directory="static"), name="static")@app.route('/session')
async def renderReactApp(request: Request):return templates.TemplateResponse("index.html", {"request": request})
by this React app get served and React routing also works fine at client side
but as soon as client reloads on a route which is not defined on server but used in React app FastAPI return not found
to fix this I did something as below.
@app.route('/network')
@app.route('/gat')
@app.route('/session')
async def renderReactApp(request: Request):return templates.TemplateResponse("index.html", {"request": request})
but it seems weird and wrong to me as I need to add every route at the back-end as well as at frontend.
I'm sure there must be something like Flask @flask_app.add_url_rule('/<path:path>', 'index', index)
in FastAPI which will server all arbitrary path
Since FastAPI is based on Starlette, you can use what they call "converters" with your route parameters, using type path
in this case, which "returns the rest of the path, including any additional /
characers."
See https://www.starlette.io/routing/#path-parameters for reference.
If your react (or vue or ...) app is using a base path, you can do something like this, which assigns anything after /my-app/
to the rest_of_path
variable:
@app.get("/my-app/{rest_of_path:path}")
async def serve_my_app(request: Request, rest_of_path: str):print("rest_of_path: "+rest_of_path)return templates.TemplateResponse("index.html", {"request": request})
If you are not using a unique base path like /my-app/
(which seems to be your use case), you can still accomplish this with a catch-all route, which should go after any other routes so that it doesn't overwrite them:
@app.route("/{full_path:path}")
async def catch_all(request: Request, full_path: str):print("full_path: "+full_path)return templates.TemplateResponse("index.html", {"request": request})
(In fact you would want to use this catch-all regardless in order to catch the difference between requests for /my-app/
and /my-app
)