Full page reload or manual DOM cleanup after a failed Turbo Stream upgrade?
0 reputation · 07 Dec 2021, 08:39 UTC
0 reputation · 07 Dec 2021, 08:39 UTC
The goal is to return the application to a consistent UI state after a Turbo Stream upgrade fails, preserving any unsaved form data while avoiding duplicate or stale Stream‑generated elements. Turbo Drive can be configured to either perform a full page reload or stay on the current page when a visit error occurs, but a full reload discards client‑side state that Turbo would normally keep. Conversely, leaving the page unchanged requires manually removing only the elements inserted by the failed Stream response, which risks deleting legitimate concurrent updates if selectors are not precise.
Developers can also implement a custom error handler that restores Turbo Frame snapshots from the cache, yet there is no built‑in way to roll back JavaScript or CSS assets loaded during the failed upgrade, potentially leaving the app in a mixed‑version state. Which recovery strategy better protects unsaved client‑side state? How can a cleanup routine safely target only the Stream‑added DOM nodes without affecting other updates? Is there a practical method to revert loaded assets without triggering a full page reload?
To protect unsaved client-side state, avoid a full page reload. A full reload is the most reliable way to ensure DOM and asset consistency, but it destroys all non-persisted form data and volatile JavaScript state. Instead, use a combination of Turbo Frame snapshots for structural recovery and targeted data-attribute cleanup for orphaned elements.
Turbo Streams are additive or transformative; they do not operate as atomic transactions. If a stream response contains multiple turbo-stream elements and the connection drops or a server error occurs mid-processing, the browser may have already applied some changes. Because Turbo does not natively "roll back" the DOM to a previous state upon a 500 error, you are left with a partial update.
To safely target only the nodes added by a failed stream without affecting concurrent updates, follow these steps:
data-turbo-stream-id="request-123") or a general marker like data-stream-generated.turbo:visit:error or a global fetch interceptor to detect the failure.// Example: Remove elements from a specific failed request
const failedElements = document.querySelectorAll('[data-turbo-stream-id="request-123"]');
failedElements.forEach(el => el.remove());
turbo-frame, trigger a reload of that specific frame to pull the last known good state from the Turbo cache, preserving the rest of the page state.There is no practical method to revert loaded CSS or JavaScript assets without a full page reload. Browser APIs do not support "unloading" a script or stylesheet once it has been executed or parsed into the CSSOM. If a failed upgrade has introduced mismatched asset versions, the application remains in a mixed-version state until a full reload occurs.
To refine this recommendation: Are your Turbo Stream responses delivering multiple independent updates in a single request, or a single update to a single frame? If it is the latter, frame-level snapshots are sufficient; if the former, the data-attribute tracking mentioned above is mandatory.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.