No-JS progressive-enhancement floor contract.
Chirp's structural advantage over diff-push UIs is that a mutating route can
serve BOTH htmx fragments (whenHX-Requestis present) AND a plain-POST
fallback (a 303 redirect or full-page render) — so the app works with
JavaScript disabled.FormAction/MutationResult and Redirect/Page
provide that fallback; a route whose only success return is aFragmentor
OOBswap silently breaks with JS off.
This check is a best-effort static heuristic over handler source AND htmx-only
mutation is a legitimate design choice, so it is INFO by default (category
nojs_floor). Apps that commit to the progressive-enhancement floor promote
it withapp.override_contract_severity("nojs_floor", Severity.ERROR).
contracts.rules_nojs_floor
| Name | Type | Default | Description |
|---|---|---|---|
type
|
|
— | |
qualified_name
|
|
— | |
element_type
|
|
— | |
description
|
|
— | |
source_file
|
|
— | |
line_number
|
|
— | |
is_autodoc
|
|
— | |
autodoc_element
|
|
— | |
_autodoc_template
|
|
— | |
_autodoc_url_path
|
|
— | |
_autodoc_page_type
|
|
— | |
title
|
|
— | |
doc_content_hash
|
|
— |
Symbols on this page
check_nojs_mutation_fallback
function
def check_nojs_mutation_fallback(router: Router) -> list[ContractIssue]
Warn when a mutating route's only success path is an htmx fragment.
Flags routes that (a) accept a mutating method, (b) are not
referenced=True(excluded transport endpoints), and (c) return a
Fragment/OOB but no FormAction/Redirect/Page/Template
fallback. Such a route is dead with JavaScript disabled.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
router
|
Router
|
— |
View source · /home/runner/work/chirp/chirp/site/../src/chirp/contracts/rules_nojs_floor.py:1