Hypermedia foundations

Start from progressive enhancement

Build core navigation and submission from real links and forms before improving it with asynchronous swaps.

Progressive enhancement means building the working baseline first and layering improvements on top. For HTMX that ordering is natural, because every hx-* attribute sits on an element that can already do the job by itself.

Start with an interaction the browser already understands:

<form action="/search" method="get">
  <label>
    Search
    <input type="search" name="q">
  </label>
  <button>Search</button>
</form>

Without JavaScript, the browser navigates to /search?q=... and the server returns a complete results page. That URL can be refreshed, bookmarked, and shared. Nothing about this form knows HTMX exists.

Now enhance the same form:

<form action="/search" method="get"
  hx-get="/search"
  hx-target="#results"
  hx-push-url="true">
  <!-- the same controls -->
</form>

When the script has loaded, HTMX intercepts the submission, updates only #results, and records the meaningful search URL in the address bar. When it has not loaded, the browser sees an ordinary form and follows action and method. The action, method, named control, and submit button still define the fallback, which is why they stay in the markup instead of being replaced by the hx-* attributes.

The common way to break this is skipping the baseline. A form with only hx-get and no action does nothing without the script; there is no fallback to fall back to. If you spot elements like that in a review, the enhancement order went backwards.

Who hits the fallback in practice? Visitors on a flaky connection where the script has not arrived yet, browsers with scripts blocked, and crawlers that read your HTML without running JavaScript. It is a real audience, not a hypothetical one.

Progressive enhancement does not require both experiences to look identical. It requires the essential task to remain understandable and usable when the script fails, is blocked, or has not loaded yet.

Disable JavaScript and complete the flow. If you cannot, fix the HTML and server routes before adding more HTMX behavior.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →