Skip to main content

max / quasi

State that a described route answers one Outcome and assumes JS
Author: Max Johnson <me@maxj.phd> · 2026-08-28 20:02 UTC
Signed with PGP, not checked
Commit: c31a778a91d59edb062c1c9abbd305d76db088e3
Parent: b9e4727
1 file changed, +40 insertions, -0 deletions
@@ -45,6 +45,46 @@
45 45 //! a [`Destination::External`], and is left alone for the reason given there: a
46 46 //! method that is ignored is simpler than two shapes of action.
47 47 //!
48 + //! # A described route answers one [`Outcome`], and assumes a client that runs JS
49 + //!
50 + //! Decided 2026-08-28, `b4304bb1`. A route answers once. It does not answer one
51 + //! way for a client that arrived with htmx and another way for a client that
52 + //! brought no JS at all. This is a property of the vocabulary rather than a
53 + //! limitation of any host: a description says what changed, and something has to
54 + //! be running on the other end to apply that to part of a page. Progressive
55 + //! enhancement stays an Askama concern, in the templates a conversion has not
56 + //! reached.
57 + //!
58 + //! The position is a promise about who a described surface serves, so the
59 + //! evidence behind it travels with it. Measured across the MNW server on
60 + //! 2026-08-28: 72 sites branch on whether the request came from htmx, over 23
61 + //! files, 56 of them under `src/routes/api/`. They are three shapes, and only
62 + //! the first is progressive enhancement.
63 + //!
64 + //! 1. **Re-render the whole page with the user's input preserved.** Three route
65 + //! files: `src/routes/auth.rs` (login), `pages/email_actions/password.rs`
66 + //! (password reset, with the emailed token intact), and
67 + //! `pages/public/join_wizard.rs` (username and email preserved). All three
68 + //! are public or auth routes. None is under `routes/pages/dashboard/`.
69 + //! 2. **Degrade to the error page.** htmx gets a toast or an inline status, a
70 + //! plain request gets the error. The dominant shape by far, and the one every
71 + //! dashboard site uses, all of them through a single `wizard_validation_toast`
72 + //! helper. There is no full-page re-render anywhere in the dashboard.
73 + //! 3. **Redirect or hand back a file.** `HX-Redirect` against a plain redirect,
74 + //! or a CSV or JSON download. Not a question about assembling a page.
75 + //!
76 + //! Every route doing real progressive enhancement is public, and the public tier
77 + //! stays in Askama, so the position costs nothing where conversion is planned.
78 + //!
79 + //! The consequence, stated so a later reader does not have to find it: describing
80 + //! a **public** page reopens this. A described public page is unreachable without
81 + //! JS. That is a product decision to make deliberately on the day it comes up,
82 + //! not a bug to file against the router.
83 + //!
84 + //! MNW's `src/fragment_redirect.rs` is a separate mechanism, sending a direct
85 + //! navigation to a fragment endpoint back to its parent page. It is not one of
86 + //! the 72 and does not bear on this.
87 + //!
48 88 //! [`Destination`]: crate::Destination
49 89 //! [`Destination::External`]: crate::Destination::External
50 90 //! [`Action::method`]: crate::Action::method