#header #htmx #axum #web #http

htmxtools

A lightweight Rust crate for working with HTMX headers, specifically designed to integrate seamlessly with axum

3 releases

new 0.1.2 Jan 2, 2025
0.1.1 Jan 2, 2025
0.1.0 Jan 2, 2025

#611 in Network programming

Download history 307/week @ 2024-12-29

308 downloads per month

MIT/Apache

83KB
2K SLoC

htmxtools

A lightweight Rust crate for working with HTMX headers, specifically designed to integrate seamlessly with axum.

HTMX is a library that enhances HTML with AJAX capabilities, and it relies heavily on custom headers to enable dynamic interactions. The htmxtools crate simplifies handling these headers in Rust, enabling you to easily extract, process, and respond with HTMX-related data.

Features

  • Request Extractors: Easily extract HTMX headers from incoming requests.
  • Response Builders: Conveniently build responses with HTMX headers.
  • Axum Integration: Built on top of typed-headers in axum-extra for seamless integration with the axum.
  • Auto Vary: Correctly handle response caching by automatically add the Vary header to responses based on the extracted HTMX headers.

Usage

To use htmxtools, run the following command in your project directory:

cargo add htmxtools

If you don't want to use axum, you can still use the htmxtools crate with other web frameworks. The crate implements headers::Header trait for all HTMX headers, so you can easily extract and build headers in any framework that supports headers::Header.

To use htmxtools without axum, run the following command in your project directory:

cargo add htmxtools --no-default-features

Request Extractors

To extract HTMX headers from incoming requests in axum, you can directly use headers in htmxtools::request in your handler functions as they implement FromRequestParts and OptionalFromRequestParts traits.

Here's an example of extracting the hx-request header:

use axum_core::response::IntoResponse;
use htmxtools::request::HxRequest;

async fn handler(hx_request: Option<HxRequest>) -> impl IntoResponse {
    if hx_request.is_some() {
        "This is an HTMX request"
    } else {
        "This is not an HTMX request"
    }
}

Here's another example of extracting the hx-target header:

use axum_core::response::IntoResponse;
use htmxtools::request::HxTarget;

async fn handler(hx_target: HxTarget) -> impl IntoResponse {
    format!("The target is: {}", hx_target.as_str())
}

async fn another_handler(hx_target: Option<HxTarget>) -> impl IntoResponse {
    match hx_target {
        Some(target) => format!("The target is: {}", target.as_str()),
        None => "No target specified".to_string(),
    }
}

Response Builders

To build responses with HTMX headers in axum, you can use headers in htmxtools::response in your handler functions as they implement IntoResponseParts and IntoResponse traits.

Here's an example of building a response with the hx-push-url header:

use axum_core::response::IntoResponse;
use htmxtools::response::HxPushUrl;
use http::Uri;

async fn handler() -> impl IntoResponse {
    HxPushUrl::url(Uri::from_static("/new-url"))
}

Here's another example of building a response with hx-retarget and hx-reswap header:

use axum_core::response::IntoResponse;
use htmxtools::response::{HxReswap, HxRetarget};

async fn handler() -> impl IntoResponse {
    (HxReswap::inner_html(), HxRetarget::from_static("#body"), "<div></div>")
}

Auto Vary

To automatically add the Vary header to responses based on the extracted HTMX headers in axum, you can use the AutoVaryLayer in htmxtools::auto_vary.

To use the AutoVaryLayer, you need to enable the auto-vary feature in your Cargo.toml.

Here's an example of using the AutoVaryLayer:

use axum::Router;
use htmxtools::auto_vary::AutoVaryLayer;

fn app() -> Router {
    Router::new().layer(AutoVaryLayer)
}

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~1.2–8MB
~74K SLoC