Using hx-target with Templates




Check out a free preview of the full HTMX & Go course

The "Using hx-target with Templates" Lesson is part of the full, HTMX & Go course featured in this preview video. Here's what you'd learn in this lesson:

ThePrimeagen debugs an issue with a web application where the response HTML is being placed in the wrong element. They identify the problem and solve it by setting a target element using the hx-target attribute. They then demonstrate how to make the code more efficient by rendering only the necessary content using a template block. Finally, they show how to further optimize the code by targeting a specific div element for replacement instead of the entire body.


Transcript from the "Using hx-target with Templates" Lesson

>> Let's debug what happened and then we're gonna fix the issue. So if we go back to here, let's open up the Chrome DevTools. Okay, it'll make life easy having these available. So let's just refresh this and I'm gonna hit the word Count. And now let's look at the response of Count, okay?

Cuz we can see we made the request. The Headers look like we made a post to localhost 42069/count. So we have the right path, we did get a nice response, which is this right here. And if we look at the response HTML, look at what we sent down.

We sent down the entire document. Now, HTMX does a little bit of a trick. If it receives an entire document, it will only select out the body content. It'll just kind of go, okay, obviously you don't need these new headers, you don't need all this stuff, you just need the body content.

And so put the body content into the requesting div, which is obvious what happened if you open up the element and you look at button, you'll notice that button has the exact same stuff that Count has right here. So oopsie daisy, we just sent down, and we just put it into the button.

So let's solve this, it's actually a pretty simple solve. We need to set a target. So I'm gonna go like this, hx-target. So if you don't know what target is, target allows you to specify which element should receive this content after the AJAX request. You can use a CSS selector or a series of basic supported JavaScript selectors.

They're from, you can read about them on MDN. So you can do find, next, previous, this, closest, or a CSS selector. So I'm gonna go body. There we go. So just do whatever you're doing, but attach it to the body. So if you're using Air, it will automatically recompile, if you're not using Air, you're gonna have to execute it yourself.

And now look at that it just says here and it just counts. But I mean, let's be real for a second, is that great? Do we want to always be responding and replacing the body, is that just how you want to live your life? I've seen head shakes all over the place, absolutely.

So let's try to boil this down just a touch more, how does that sound? Let's make it a little bit better, all right. So I'm gonna jump back over to, well, first off, you'll notice also the HTML is correct. So good thing to always double check. All right, HTML is correct.

So let's go over here and I'm gonna create a new block. Block, we'll call this thing, count. And I'm gonna go up here and I'm just gonna take out the body and I'm gonna just post it in here. And then I'm gonna go back up and I'm gonna go template count.

So there we go. So I'm gonna just say, hey, we want this small little bit. I don't need to send down the entire response, I'm just gonna send down the things that I think are worthy of change. Feels pretty good, right? I'll let everyone take a moment. I'm sure you guys can program these templates pretty easily.

They're fairly well understood. I assume no one has a question about what this means. But in case you do render template named count and pass in the object that was passed to me. Pretty straightforward, right? All right, and this block says, I'm block count, and I accept an object, and I will now use that object right here.

Okay, everyone gets it pretty straightforward, easy peasy lemon squeezy. So now that we have that, let's jump back over to our code and in our post, instead of rendering the index, let's render just that count. So I'm gonna take the count, I'm gonna replace index with count. So there we go, fantastic.

So now if I were to run the server, let's just refresh everything so we can see it's all in the Into its original state. When I press this, we still get this beautiful updating, but it is the entire body not as cool, but notice that the response now is just this little bit, better?

Yes, best? No, we can all agree this is not best, it's just simply better. So we should probably try to make it even better, okay? So I'm gonna go back here, let's just make sure this is what I wanted to do. Okay, yeah, I didn't wanna do it here, all right.

So let's try rendering something slightly different. Let's change how we do this so called HTML. So what I'm gonna do here is I'm gonna take the button out of here. I'm gonna put it right here and then I'm gonna add a digit div and call id, how about this one count, right?

Fantastic, and instead of targeting the body, let's target count. So I'm just gonna use a CSS selector again, to just simply say, hey, when you press this make a post request, but I want you to target the div count for the replacement. And now my count template literally looks like this.

It's nothing, right? It's absolutely nothing. But we're still gonna refer to it, which means that when I go to the server, I'm still only rendering that, but when I go to the client, I'm only gonna be replacing this small amount of text. So it is now as minimally defined as possible.

Second thing I'd like to highlight right here, is the entirety of the behavior of this, is within eyeshot of four lines of code. So often they refer to this as locality of behavior. You can kind of understand what's happening in its entirety by just looking at a few lines of very declarative code.

So HTMX tends to be a very declarative driver of your application. Now, there are some imperative procedural parts of HTMX, but for the most part it's very declarative style. So, now I'm gonna go back here, we'll now press Count and we'll still increment when we look at our Element, you'll notice that it beautifully just counts right there.

We're no longer replacing body, and when you look at the Network, we're just replacing it with the string 5. Now, we could even make it smaller. We could even just make it so it only transfers down just that singular byte. But I hate to let you people down, if you're transferring less than 1500 bytes, it's all the same, right?

That's called the TCP packet. That's the MTU, the maximum transmission unit. So, whether you're transferring one byte or 1499, it's pretty much all the same. So you're not making any more W's at this point. So now that we did that, absolutely fantastic. Hopefully everyone kind of kept up with that idea.

You can kinda see how we started targeting HTMX to make updates within the application.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now