Router Recreated Mid-Navigation Causes Frozen UI After Save
Version: 3.1.0 Date: 2026-06-12
Goal: Fix a race condition where saving a source or storage left the UI frozen on the edit screen — URL changed correctly but the page stayed stuck and the Save button was grayed out.
Solution: createBrowserRouter was called inside App with routes(state.data), so every re-render of App produced a new router instance. The onSuccess callback in StepStorageForm invalidated ['status'], which triggered a re-render of App and a new router while the navigate('/workflows') transition was still in flight. The new router initialized on the old URL, the old router finished pushing the new URL, and the two were forever desynchronized. Fix: create the router exactly once at module level (const router = routes()). ActivatedRoute now reads status itself via useQuery(['status']) instead of receiving it as a prop from the router.
Files Modified:
ui/src/App.tsx— router created once at module level, removeduseQuery(['status'])fromAppui/src/routes.tsx—routes()takes no arguments;ActivatedRoutereads['status']viauseQueryinternallyREADME.md— added "Router singleton" convention note under UI architecture section