Beyond hx-indicator: Alternative Approaches for htmx Loading Indicators
Purpose
hx-indicator
tells htmx which element to target for displaying a loading indicator while data is being fetched from the server.
How it works
- You add the
hx-indicator
attribute to an element in your HTML. - This element acts as a reference for htmx.
- When an element with
hx-indicator
is involved in an htmx request (like clicking a button withhx-get
):- The specified element gets a CSS class
htmx-request
added to it.
- The specified element gets a CSS class
Benefits
- This
htmx-request
class allows you to style the indicator element using CSS. You can use this class to show spinners, progress bars, or any visual cue that informs the user about the ongoing request.
Example
<button hx-get="/data" hx-indicator="#loading-indicator">Get Data</button>
<div id="loading-indicator">Loading...</div>
In this example:
- You can style this class in your CSS to display a "Loading..." message or any preferred indicator.
- During the request, the element with
id="loading-indicator"
will have thehtmx-request
class added. - Clicking the button triggers an
hx-get
request.
- You need to use CSS to style the
htmx-request
class for the visual effect. hx-indicator
doesn't handle the indicator itself, it just tells htmx which element to target for adding thehtmx-request
class.
Basic Loading Indicator
<button hx-get="/data" hx-indicator="#spinner">Get Data</button>
<img id="spinner" class="htmx-indicator" src="/img/loading.gif" alt="Loading..." style="display: none;">
This example:
- When the button is clicked, the
htmx-request
class is added, likely overriding thedisplay
property in your CSS to show the spinner. - The CSS
display: none;
hides the image initially. - The
hx-indicator
points to the#spinner
element. - Uses an
<img>
tag with a pre-defined loading GIF as the indicator.
Multiple Indicators on a Page
<div id="content">
<button hx-get="/data1" hx-indicator=".content-indicator">Load Data 1</button>
<button hx-get="/data2" hx-indicator=".content-indicator">Load Data 2</button>
</div>
<div class="content-indicator htmx-indicator" style="display: none;">Loading...</div>
- This ensures only one indicator is shown at a time, regardless of which button is clicked.
- The
hx-indicator
on each button targets the same class. - Uses a single indicator element with class
content-indicator
for both buttons.
<a hx-get="/data" hx-indicator="span">Loading data... <span class="htmx-indicator"></span></a>
- When the request starts, the
htmx-request
class is added, likely affecting styles of both<span>
elements. - The second
<span>
with classhtmx-indicator
displays the hourglass symbol (assuming you have a font with that character). - The first
<span>
shows the text "Loading data..." hx-indicator
is set to"span"
to target any child<span>
element within the<a>
tag.- Uses an inline indicator with text.
Manual CSS Classes
- Use JavaScript to toggle the
loading
class based on the request lifecycle (started/finished). - Add a class like
loading
to the element that needs the indicator. - Instead of relying on
hx-indicator
, you can directly manage the loading indicator with CSS classes.
Example
<button id="my-button" hx-get="/data">Get Data</button>
<script>
document.getElementById('my-button').addEventListener('hx:request', () => {
document.getElementById('my-button').classList.add('loading');
});
document.getElementById('my-button').addEventListener('hx:response', () => {
document.getElementById('my-button').classList.remove('loading');
});
</script>
<style>
.loading {
/* Add styles for loading indicator (e.g., opacity, spinner) */
}
</style>
Third-party Libraries
- These libraries offer various animations and customization options.
- Several JavaScript libraries specialize in creating loading indicators.
Server-side Rendering
- This approach eliminates the need for client-side manipulation.
- If your server-side framework supports it, you can render the loading indicator directly in the initial HTML response.
- For server-side rendering capabilities in your framework, explore that option.
- If you want pre-built animations and customization, consider third-party libraries.
- If you need a simple solution and have basic CSS skills, manual CSS classes might be sufficient.