I have a React-Typescript UI running on top of a flask API. I'm using BrowserRouter for routing paths in the UI. For a couple routes I want the react app to just fall back to rendering raw HTML returned by the underlying flask app. ie I don't want to map the route to an element, just fetch the route from the back-end. Is there some way to tell the route to behave this way?
Edit: Here's a detailed outline of the issue:
The react app is a thin client over top of a flask app. When requests come in the front door, the flask app either handles the request, or re-routes it to the react UI:
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
if path.startswith("api/v0/"):
abort(404)
if current_user.is_authenticated and current_user.is_active:
return render_template("ui/index.html")
elif current_user.is_authenticated:
return render_template("inactive.html")
else:
return render_template("unauth.html")
The flask app has a /logout route, that unloads the current user and then redirects to the (flask-handled) / route, prompting unauth.html to load. This works fine when I directly navigate to /logout.
The React UI has its own router for loading page elements. Loading /ui/index.html launches the app, and it essentially defines its own namespace for rendering pages:
<Routes>
<Route path="" element={<Navigate replace to="/collections" />} />
<Route path="/" element={<App />}>
<Route path="home" element={<Home />} />
<Route path="collections">
<Route path=":collectionId" element={<CollectionDetail />} />
<Route index element={<CollectionsList />} />
</Route>
<Route path="users">
<Route index element={<UserList />} />
</Route>
<Route path="images/:imageId" element={<ImageDetail />} />
</Route>
<Route
path="*"
element={
<main>
<p>Page not found</p>
</main>
}
/>
</Routes>
The issue is I have no way to break out of the react app context once I'm in it. Specifically, placing a <Link />
to "/logout" takes the default route in the app and renders "Page not found". But if I navigate directly to /logout the flask app handles it correctly.
One solution might be to move all the html-generating flask responses to the react app, but I think this would complicate routing in the flask app itself- ideally flask is only aware of the single entry point to the react app at /ui/index.html
CodePudding user response:
The Link
component has a reloadDocument
prop that can be used to "skip client side routing and let the browser handle the transition normally (as if it were an <a href>
)". In doing so this a page request is made to the server and can be handled there.
See Link.
interface LinkProps extends Omit< React.AnchorHTMLAttributes<HTMLAnchorElement>, "href" > { replace?: boolean; state?: any; to: To; reloadDocument?: boolean; }
Example:
<Link to="/logout" reloadDocument>Logout</Link>