#htmx #html #frontend

Day 6: Loading States

Welcome to Day 6. Networks are slow. Users are impatient. We need to show them something is happening.

The htmx-request Class

When htmx sends a request, it adds the htmx-request class to the triggering element. You can use CSS to style this.

button.htmx-request {
    opacity: 0.5;
    cursor: wait;
}

hx-indicator

For more controls, like showing a hidden spinner elsewhere, use hx-indicator.

<button hx-post="/save" hx-indicator="#spinner">
    Save
</button>

<img id="spinner" class="htmx-indicator" src="/loader.svg"/>

The CSS Magic

You need to include this basic CSS in your app (or write your own logic):

.htmx-indicator {
    display: none; /* Hidden by default */
}
.htmx-request .htmx-indicator {
    display: inline; /* Show when parent is requesting */ 
}
.htmx-request.htmx-indicator {
    display: inline; /* Show when it IS the indicator */
}

Wait, htmx manages the classes for you.

  1. When requesting, htmx puts .htmx-request on the indicator.
  2. This toggles the opacity/display if you set up your CSS right.

Simple approach:

.my-spinner {
    opacity: 0;
    transition: opacity 200ms;
}
.htmx-request .my-spinner {
    opacity: 1;
}

Challenge for Day 6

  1. Create a “Search” button.
  2. Put an SVG spinner icon inside the button.
  3. The spinner should be invisible normally.
  4. When clicked, the spinner appears next to the text “Searching…”.

Solution:

<style>
  .loader { display: none; }
  .htmx-request .loader { display: inline-block; }
</style>

<button hx-get="/search">
    Search
    <span class="loader">🌀</span>
</button>

Smooth. Tomorrow: Out Of Band Swaps.