- Press
space
for next slide - Press
shift + space
for previous slide - Use ±200% zoom for presentation mode
- For reading after the talk use the
Progressive Enhancement with HTMX
Or what happens when there is no JavaScript
Speaker
html+css+js &
clojure
developer &
designer
↑ Paul
Why Progressive Enhancement
Part 1
Rule of Least Power
[...] suggests choosing the least powerful language suitable for a given purpose.
[range from declarative to procedural]
- W3C Tim Berners-Lee, Noah Mendelsohn
What is Progressive Enhancement?
- 🔍 User visits website
- 📱 Browser has JavaScript issues
- 📖 You can still read and have basic interactions
- 🖥️ You can switch to a working browser for better UX
What is Progressive Enhancement?
Progressive enhancement (PE) is a design philosophy that provides a baseline of essential content and functionality to as many users as possible, while delivering the best possible experience only to users of the most modern browsers that can run all the required code.
- MDN
1% has no (working) JavaScript
- 🥷🏽 Privacy focused users
- 📠 Outdated browsers
- 🛠️ (Broken) Browser Add-Ons
- ⚙️ Search Engines
- ⬇️ Error on download (unstable connections)
Why HTMX?
- 💡 Simple → easy to understand
- 🚀 Hyped (aka. active project and user base)
- 🌐 Framework-agnostic
- 🔨 No front-end build steps
- 👨🏽💻 I know how to use it
HATEOS
Hypermedia as the Engine of Application State (HATEOAS)
A REST client needs little to no prior knowledge about how to interact with an application or server beyond a generic understanding of hypermedia.
Why HTMX?
SQL → Backend → JSON →
HTTP →
JavaScript Templating → HTML
Why HTMX?
SQL → Backend → HTML →
HTTP
Welcome to my online shop
Part 2
The Shop Mockup
Level of Interactivity
Low
High
☝🏽
5/10
hx-boost
<body hx-boost="true"> <a href="/product/some-id">Generic Product</a>
hx-boost
- 🫁 Only replace the body of the page
- ⏳ Wait until the new page has fully loaded
- ⚡️ No flickering
- ✅️ Graceful degradation = progressive enhancement
hx-put & friends
<button hx-put="/api/product/cart/some-id"> Add to Cart </button>
hx-put & friends
- ❌ Only works with JS != progressive enhancement
- ⚙️ Extends limited form+post requests
hx-put & friends
<form action="/api/product/cart/some-id/add"> <button type="submit">Add to Cart</button> </form>
We need to fall back to form requests!
hx-put & friends
- ✅ Will always work without JavaScript
- 🆗 Put/Delete/... needs to be baked into endpoint
- 🆗 Can be abstracted with templating
Delete button templating example
const delete_btn = (label, url) => `<form action="${url}/delete> <button type=submit>${label}</button> </form>`
hx-trigger
<input name="q" hx-get="/search" hx-trigger="keyup changed delay:1s" hx-target="#search-results"/>
hx-trigger
<form action="/search"> <input .../> <noscript> <button type="submit">Submit</button> </noscript> </form>
Progressive Enhancement in the Backend
Part 3
Detecting HTMX
const search_handler = (request) => request.headers["hx-request"] ? render_search_results() : render_full_page()
hx-swap
<a href="/products/page/2" hx-get="/htmx/products/page/2" hx-swap="outerHTML" hx-target="main" hx-push-url="/products/page/2"> Next page</a>
hx-swap
- Replaces only a section of your page
- Backend can decide how to respond
- Makes reactive & responsive websites possible, just like SPAs
Deciding in the Backend
- You can always check for
hx-request
- Always indicates if JavaScript is available
- You can decide to add/remove parts of the page
Deciding what to show
const some_component = (has_js) => has_js ? `<MyWebComponent />` : `<div>no web component alternative</div>`
Web Components
- ⚙️ Requires JavaScript to work
- 🚀 Significant UX improvement possible
- 📄
form
as fallback option
First page load
- You can never check for
hx-request
- You don't know your clients capabilities
- → Important limit to know
Deferred Loading
<div hx-get="/graph" hx-trigger="load"> <img alt="Loading..." src="/spinner.svg"/> </div>
Deferred Loading
- Does not work, if JavaScript is missing
- "First page load problem" applies
- Can be used on subsequent
hx-swap
s - Increases response time, if some requested elements take more time to load
PE without HTMX
Part 4
You can still use JavaScript
- Progressive Enhancement always possible
- A few lines of vanilla JS can get you a long way
- You don't need React
- Still no compile step
Progressive Web Apps
- Works with MPA
- Use web workers to cache REST calls
What's next
Part 5
Accessibility side effect
- 📖 No JavaScript promotes use of semantic HTML
- ♿️ Native HTML elements are already accessible
- 🔗 URL represents state and is sharable
DX side effects
But does it scale?
- Only one service to scale horizontally
- Still stateless
- Easy vertical scaling
- Micro-frontends still possible
But animations?!
- View Transition API works with MPA
- CSS3 animations are great and easy to use
quote
When evaluating your framework do not only compare SPA options. Also include simpler approaches, like HTMX, and compare the additional benefits, like PE, for your users.