axum-htmx
axum-htmx is a small extension library providing extractors, responders, and
request guards for all htmx headers within
axum. Additionally, the library exports
const values for all of the htmx headers, so there's no need to mess with
strings in your handlers.
Getting Started
Simply run cargo add axum-htmx to add the library to your project.
If you are using the unreleased branch of axum from GitHub, you can build
against the main version of axum-htmx by adding the following to your
Cargo.toml:
[]
= { = "https://github.com/robertwayne/axum-htmx" }
Extractors
All of the htmx request headers
have a supported extractor. Extractors are infallible, meaning they will always
succeed and never return an error. In the case where a header is not present,
the extractor will return None or false dependant on the expected return
type.
| Header | Extractor | Value |
|---|---|---|
HX-Boosted |
HxBoosted |
bool |
HX-Current-URL |
HxCurrentUrl |
Option<String> |
HX-History-Restore-Request |
HxHistoryRestoreRequest |
bool |
HX-Prompt |
HxPrompt |
Option<String> |
HX-Request |
HxRequest |
bool |
HX-Target |
HxTarget |
Option<String> |
HX-Trigger-Name |
HxTriggerName |
Option<String> |
HX-Trigger |
HxTrigger |
Option<String> |
Responders
All of the htmx response headers
have a supported responder. A responder is a basic type that implements
IntoResponseParts, allowing you to simply and safely apply the HX-* headers to
any of your responses.
| Header | Responder | Value |
|---|---|---|
HX-Location |
HxLocation |
axum::http::Uri |
HX-Push-Url |
HxPushUrl |
axum::http::Uri |
HX-Redirect |
HxRedirect |
axum::http::Uri |
HX-Refresh |
HxRefresh |
bool |
HX-Replace-Url |
HxReplaceUrl |
axum::http::Uri |
HX-Reswap |
HxReswap |
axum_htmx::responders::SwapOption |
HX-Retarget |
HxRetarget |
String |
HX-Reselect |
HxReselect |
String |
HX-Trigger |
HxResponseTrigger |
String or axum_htmx::serde::HxEvent* |
HX-Trigger-After-Settle |
HxResponseTriggerAfterSettle |
String or axum_htmx::serde::HxEvent* |
HX-Trigger-After-Swap |
HxResponseTriggerAfterSwap |
String or axum_htmx::serde::HxEvent* |
* requires the serde feature flag to be enabled.
Request Guards
Requires features guards.
In addition to the extractors, there is also a route-wide layer request guard
for the HX-Request header. This will redirect any requests without the header
to "/" by default.
It should be noted that this is NOT a replacement for an auth guard. A user can
trivially set the HX-Request header themselves. This is merely a convenience
for preventing users from receiving partial responses without context. If you
need to secure an endpoint you should be using a proper auth system.
Example: Extractors
In this example, we'll look for the HX-Boosted header, which is set when
applying the hx-boost attribute to an
element. In our case, we'll use it to determine what kind of response we send.
When is this useful? When using a templating engine, like
minijinja, it is common to extend
different templates from a _base.html template. However, htmx works by sending
partial responses, so extending our _base.html would result in lots of extra
data being sent over the wire.
If we wanted to swap between pages, we would need to support both full template
responses and partial responses (as the page can be accessed directly or
through a boosted anchor), so we look for the HX-Boosted header and extend
from a _partial.html template instead.
use IntoResponse;
use HxBoosted;
async
Example: Responders
We can trigger any event being listened to by the DOM using an htmx trigger header.
use HxResponseTrigger;
// When we load our page, we will trigger any event listeners for "my-event.
async
...htmx even allow arbitrary data to be sent along with the event, which we
can use via the serde feature flag and the HxEvent type.
use HxEvent;
// Note that we are using `HxResponseTrigger` from the `axum_htmx::serde` module
// instead of the root module.
use HxResponseTrigger;
async
Example: Router Guard
use Router;
use HxRequestGuardLayer;
Feature Flags
| Flag | Default | Description | Dependencies |
|---|---|---|---|
guards |
Disabled | Adds request guard layers. | tower, futures-core, pin-project-lite |
serde |
Disabled | Adds serde support for the HxResponseTrigger* and HxLocation response headers. |
serde, serde_json |
Contributing
Contributions are always welcome! If you have an idea for a feature or find a bug, let me know. PR's are appreciated, but if it's not a small change, please open an issue first so we're all on the same page!
License
axum-htmx is dual-licensed under either
at your option.