I'm trying to learn HTMX with Go and GoFiber.
Here is my HTML page :
<script src="https://unpkg.com/htmx.org@2.0.0" integrity="sha384-wS5l5IKJBvK6sPTKa2WZ1js3d947pvWXbPJ1OmWfEuxLgeHcEbjUUA5i9V5ZkpCw" crossorigin="anonymous"></script>
<main>
<div class="grid h-screen place-items-center">
<div class="flex flex-col items-center space-y-4">
<h1 class="text-5xl font-bold mb-16">Connexion</h1>
<form hx-post="/auth" hx-target="#error-message" hx-swap="innerHTML" class="flex flex-col items-center space-y-4">
<input
type="password"
placeholder="Mot de passe"
class="input input-bordered input-primary w-full max-w-xs"
id="password"
name="password"
/>
<button type="submit" class="btn btn-primary">Connexion</button>
</form>
<div id="error-message" class="text-red-500"></div>
</div>
</div>
</main>
and here is the /auth route of my API in GoFiber
func Auth(c *fiber.Ctx) error {
// get the password on the body
clientPassword := c.FormValue("password")
// check if the password is correct
password, err := database.GetPassword()
if err != nil {
log.Fatalf("Failed to get the password: %v", err)
return c.Status(fiber.StatusInternalServerError).SendString("Internal Server Error : cannot get the password in db")
}
if clientPassword != password {
log.Println("Incorrect password")
return c.Status(fiber.StatusUnauthorized).SendString("<p class='text-red-500'>Incorrect password. Please try again.</p>")
}
log.Println("Correct password")
// redirect the client on the home page
return c.Redirect("/videos")
}
My problem is that when I send an incorrect password, the API correctly receives the request and my browser correctly receives the response with a status code of 401 and the HTML string. However, the message sent by the API does not appear in the error-message
div. Why didn't it work, and how can I fix this?
(I tried swapping the outerHTML, targeting a class insted of an id but nothing seem to work.)
HTMX by default only processes successful requests. If you want to handle 401 responses, you have two basic choices. I would say up front that I am not a fan of using 401 for this purpose, I would use 422 instead which is "unprocessable entity". It is a better fit for what is essentially a validation type of error from the perspective of a login form. Your mileage may vary.
https://github.com/bigskysoftware/htmx-extensions/blob/main/src/response-targets/README.md
If you use it, be aware that it is not enough to include the script in your page. You also need to activate it using hx-ext
: https://htmx.org/docs/#extensions
Example setup:
<script src="https://unpkg.com/htmx-ext-response-targets@2.0.0/response-targets.js"></script>
<body hx-ext="response-targets">
<form hx-post="/auth" hx-target-422="#error-message"
Adding a whole different extension library just to get one task done might seem overkill; I wouldn't want to riddle my front end with large amounts of status-code specific target directives. Fortunately HTMX is quite configurable. You can tell it that you do want to "swap" on specific response codes. https://htmx.org/docs/#requests
Example:
document.body.addEventListener('htmx:beforeSwap', function(evt) {
if(evt.detail.xhr.status == 422) {
evt.detail.shouldSwap = true;
evt.detail.isError = false;
}
});
Rinse and repeat for any other error status codes you would want to handle in your front-end. Just keep in mind that if you start to put a long list of response codes here... you may want to rethink if you actually need HTMX for your use case.