Add per-conversation URLs with client-side routing #36
Reference in New Issue
Block a user
Delete Branch "conversation-routing"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Give each conversation a deep-linkable URL (
/c/:conversationId) so threads survive refresh, support browser back/forward, and are shareable within a session. The app was already an SPA but had no router.Changes
react-router-dom; wrap the app inBrowserRouterand define routes (/for the empty/new state,/c/:conversationIdfor a thread)selectedConversationis derived from the:conversationIdparam; create/delete navigate instead of mutating local selection state/and lets the first message lazily create the conversation, so it no longer litters empty conversationsNo backend changes:
app.pyalready servesindex.htmlfor unmatched paths, and the service worker is network-first for navigations, so deep links resolve on hard refresh.Verification
Drove the real built bundle in headless Chrome against a mock backend (Docker/OIDC unavailable locally):
/c/:id+ messages; switch clears old thread instantly/c/:idloads the same conversation/; first message creates conv, navigates to/c/:newId, stream not wiped/; non-existent conversation id 404s gracefully (no crash)Verification caught and fixed a bug where the skip-ref
nullsentinel collided with the home route, leaving stale messages on "New thread".tscclean,yarn buildclean, backendpytest74 passed (unaffected).🤖 Generated with Claude Code
Give each conversation a deep-linkable URL (/c/:conversationId) so threads survive refresh, support browser back/forward, and are shareable within a session. The app was already an SPA but had no router. - Add react-router-dom; wrap the app in BrowserRouter and define routes ("/" for the empty/new state, "/c/:conversationId" for a thread) - Make the URL the source of truth for selection: selectedConversation is derived from the :conversationId param; create/delete navigate instead of mutating local selection state - Load a thread's messages in a URL-keyed effect that clears immediately for an instant switch, with a stale-response guard - Preserve the optimistic message + in-flight stream when the first message lazily creates a conversation and navigates into it (skip-ref keyed on the new id, guarded against the null/home-route collision) No backend changes: app.py already serves index.html for unmatched paths. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>