Welcome back, coders! Now that you’ve dipped your toes into the htmx waters, it’s time to wade in a little deeper. Today, we’re diving headfirst into htmx attributes — the secret sauce that makes your Razor Pages dance with interactivity. So, buckle up and get ready for some fun!
Understanding the Core htmx Attributes
htmx gives you a bunch of powerful attributes to play with. Let’s break them down.
hx-get, hx-post, hx-put, hx-delete
These are your bread and butter when it comes to making HTTP requests from the client-side.
- hx-get: Sends a GET request to the server.
- hx-post: Sends a POST request, often used for submitting forms.
- hx-put: Sends a PUT request, usually for updating data.
- hx-delete: Sends a DELETE request, often for, you guessed it, deleting data.
Here’s a quick example using hx-get and hx-post.
Index.cshtml
@page @model IndexModel <!DOCTYPE html> <html> <head> <title>htmx Attributes Demo</title> <script src="https://unpkg.com/htmx.org"></script> </head> <body> <h1>htmx Attributes Deep Dive</h1> <!-- GET Request Example --> <div id="get-result"> <button hx-get="/Index?handler=GetMessage" hx-target="#get-result">Fetch Message</button> </div> <!-- POST Request Example --> <div id="post-result"> <form hx-post="/Index?handler=PostMessage" hx-target="#post-result"> <input type="text" name="message" placeholder="Enter a message"> <button type="submit">Send Message</button> </form> </div> </body> </html>
Index.cshtml.cs
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System; namespace YourNamespace.Pages; public class IndexModel : PageModel { public IActionResult OnGetGetMessage() { var message = "Hello from the server!"; return Content($"<p>{message}</p>", "text/html"); } public IActionResult OnPostPostMessage(string message) { var responseMessage = $"<p>You said: {message}</p>"; return Content(responseMessage, "text/html"); } }
Targeting, Swapping, and Triggering
Now let’s talk about how you can make these requests even cooler.
hx-target
This tells htmx where to inject the server’s response. In the previous example, hx-target="#get-result"
ensures the message gets rendered right where you want it.
hx-swap
Controls how the response content gets swapped into the target element. Options include:
outerHTML
(Default): Replaces the entire target element.innerHTML
: Replaces the contents of the target element.beforebegin
,afterbegin
,beforeend
,afterend
: Places content in relation to the target element.
Example usage:
<button hx-get="/Index?handler=GetMessage" hx-target="#get-result" hx-swap="innerHTML">Fetch Message</button>
This will replace only the content inside the #get-result
div.
hx-trigger
Decides when an htmx request should be made. You can trigger requests on events like click
, load
, mouseover
, or even custom events.
Example:
<div hx-get="/Index?handler=AutoMessage" hx-trigger="load" hx-target="#auto-message"> <p id="auto-message">Loading message...</p> </div>
This will automatically trigger a request when the page loads. Super handy for preloading content.
Making It All Work Together
Here’s a little challenge for you: Let’s build a simple CRUD interface using these attributes.
Index.cshtml
@page @model IndexModel <!DOCTYPE html> <html> <head> <title>CRUD with htmx</title> <script src="https://unpkg.com/htmx.org"></script> </head> <body> <h1>Simple CRUD Interface</h1> <div id="message-list"> <button hx-get="/Index?handler=GetMessages" hx-trigger="load" hx-target="#message-list">Load Messages</button> </div> <div> <form hx-post="/Index?handler=AddMessage" hx-target="#message-list"> <input type="text" name="message" placeholder="New message"> <button type="submit">Add Message</button> </form> </div> </body> </html>
Index.cshtml.cs
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System.Collections.Generic; namespace YourNamespace.Pages; public class IndexModel : PageModel { private static readonly List<string> Messages = new(); public IActionResult OnGetGetMessages() { var messagesHtml = string.Join("", Messages.Select(m => $"<p>{m}</p>")); return Content(messagesHtml, "text/html"); } public IActionResult OnPostAddMessage(string message) { if (!string.IsNullOrWhiteSpace(message)) { Messages.Add(message); } var messagesHtml = string.Join("", Messages.Select(m => $"<p>{m}</p>")); return Content(messagesHtml, "text/html"); } }
Why htmx Attributes Are Game-Changers
When you combine all of this, htmx’s attributes make building interactive pages simple and expressive. No overkill frameworks. No complicated state management. Just Razor Pages doing what they do best: serving HTML, and htmx making it feel dynamic.
Stay tuned for more because we’ve only scratched the surface of what htmx can do. Next, we’ll dive into advanced usage patterns that will make your Razor Pages even more powerful.