Maud, axum, src="path/to/file" not working

i am trying to use htmx, </> htmx ~ Documentation and basically, if i include the cdn, everything works as expected. but when trying to include htmx as a file, it does not work. ive tried ../'s with no luck. i even put std::fs::read("htmx.min.js").unwrap(); to see if the program would panic and to see if htmx.min.js was in the same working directory, and it was, just fine. it would be fine to use the cdn, as the files hash is included in the script tag (no way to tamper with it). but id prefer a local installation.

use axum::{routing::get, Router};
use maud::{html, Markup};

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/", get(root))
        .route("/hello", get(hello));

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();

    axum::serve(listener, app).await.unwrap();
}

async fn root() -> Markup {
    html! {
        script src="htmx.min.js" {}
        button hx-get="/hello" hx-target="#hello" {
            "Click me!"
        }
        div id="hello" {}
    }
}

async fn hello() -> Markup {
    html! {
        "hello"
    }
}
async fn root() -> Markup {
    html! {
        script src="htmx.min.js" {}
        button hx-get="/hello" hx-target="#hello" {
            "Click me!"
        }
        div id="hello" {}
    }
}

The resulting Markup instance will render to a fragment like

<script src="htmx.min.js">
<button hx-get="/hello" hx-target="#hello">Click me!</button>
<div id="hello></div>

Maud doesn't look at the semantic content of the markup it generates - it just generates it. That script tag for "htmx.min.js" is emitted without any regard for whether it will be valid once interpreted by a browser; you get what you asked for, and no more or less than that.

When this fragment is rendered in the browser, the browser will see the relative URL "htmx.min.js" and request it from the origin of the page. For example, if this fragment came from http://localhost:3000/, then the browser will request http://localhost:3000/htmx.min.js in order to populate that script element.

Does your application serve htmx.min.js from the appropriate URL? I don't think it does - it only serves two markup fragments, at / and /hello, so a request for /htmx.min.js will result in a 404. You may need to add an endpoint to serve your scripts, for example.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.