Repository navigation
Did Place order work? Show the pending state (Web HIG tip #16) #33
frozonfreak
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Someone taps Place order on a slow connection. Nothing changes on screen. Did the tap register? Should they try again? A missing pending state leaves them guessing. If repeat requests reach an unprotected endpoint, that uncertainty can also become a duplicate order.
Web HIG tip #16 (Quick #45): Server mutations must show pending UI immediately — disable submit, show spinner.
Why it matters
A request in flight is invisible unless the interface makes it visible. Without that signal:
The full HIG covers this in §4.2, Async Mutation & Server Action State Model: forms executing server mutations MUST supply immediate visual feedback without waiting for server response round-trips. Quick #47 adds that critical mutations should be idempotent. §4.5 says important mutations SHOULD use idempotency keys at the product/API layer. That protects the intended effect of an operation when requests repeat; it does not guarantee a single network request.
Before and after
This bare native POST form has no application-specific pending feedback. The browser may show navigation progress, but the button does not explain what is happening:
Here is a client-side pending-state illustration, not a complete checkout. It keeps native POST navigation and assumes this is the form's only submission handler. It disables the single submit button and guards against later
submitevents while pending:The handler updates the label, spinner and status text synchronously, before waiting for a response. A fast navigation may replace the page before that feedback is painted or announced.
role="status"is a polite live region, not a promise that a screen reader will speak before navigation.The guard covers only later
submitevents on this page while its flag is set. A directform.submit()call bypasses that event. Other tabs, reloads and retries remain outside its scope. Thepageshowhandler resets the UI when this document returns from the back/forward cache; it does not establish whether an order succeeded.This snippet does not handle a blocked or cancelled navigation, an in-page request failure, or a successful order response. A real flow needs outcome and recovery UI, preserved input, and server-side validation and security protections. Do not drop this handler into a framework-managed form without adapting it to that form's lifecycle.
A hidden input named
idempotency_keywould not solve duplication by itself. The server must implement deduplication, including concurrent requests, and bind a key to the same intended operation and authorised caller. Reuse that key for retries of that operation, not unrelated new orders; define payload checks and expiry. If a response is lost, do not assume the order failed. Check its outcome before starting another order. Those server and recovery pieces are outside this example.Do this instead
Quick check for your app
Use a test environment, not a real payment or production invite. Slow down the response and check that the label and pending indicator update without waiting for it. Try repeated clicks and, where supported, Enter submission. Inspect the network, but also verify the server-side result: deliberately repeated requests for the same operation should not create duplicate orders. Test concurrent requests too.
Exercise validation failures, lost responses, recoverable errors, Back navigation and a retry of the same operation. Check keyboard use, reduced motion and screen-reader feedback; for native navigation, inspect the destination page as well as the pending state. Suitable automated browser and server tests can catch these problems. Pair them with manual checks on the browsers and assistive technology your audience uses. A green suite is evidence for what it actually exercised, not proof that every failure path works.
The Web HIG is an open set of guidelines for how the web should behave, not a component library. Design systems define how it looks. The Web HIG defines how it behaves.
All reactions