Interactive zero Javascript sites with django

How to rocket-start your frontend with HTMX

Ronny Vedrilla
ambient-digital
6 min readNov 26, 2021

--

Photo by SpaceX on Unsplash

There are a lot of reasons why to avoid Javascript in your django project. Some of them are valid, others are not. Being a proficient python web developer doesn’t mean that you also do well in Javascript. Relying a lot on a language and its ecosystem which you don’t feel comfortable with might be one of the valid reasons. Another one might be that you are building an application and want to focus on your backend-specific challenge and not fiddle around too much with the frontend.

Either way — and as seen in all of the last djangoCons — not using Javascript is a big issue for python web developers. The classic way of getting interaction in the frontend without using a proper framework like Angular.js, react.js or vue.js would be to grapple with jQuery.

A new hope

Luckily and thanks to the latest djangoCon the word has been spread about HTMX. This javascript package provides a simple way of avoiding self-written Javascript code by magically interpreting special HTML attributes on DOM elements.

In a nutshell, HTMX can trigger an AJAX call to your backend and replace some part of your DOM with the result. The backend would do some things and return a new HTML snippet which is inserted in your page.

Have a look at this super simple example from the HTMX website. We see a button that has a special HTMX attribute containing the URL to post a request to. When the request is returned, the result will replace the outerHTML of the button:

Photo by Faris Mohammed on Unsplash

That’s neat! But…

This solution is neat but working this way will leave heaps of use-cases unhandled — or at least not properly dealt with. Imagine, you are building a website where related content is distributed all over the page. Picture the scenario when you can close a ticket on your dashboard. Naturally, you would need to remove the closed ticket from the dashboard. But probably there is an open-ticket counter in the main navigation and maybe a link to the ticket in your to-do-list-sidebar.

Handling all these cases with the approach shown above is not possible — at least not in a way you’d like to show your colleagues. So is HTMX just a less-JS replacement for jQuery?

Example sketch of our ticket dashboard

The magic of events

Obviously, there is more to HTMX than meets the eye. It has an extensive, built-in event handling mechanism which we can utilise with django very conveniently.

Looking at the frontend, you can add an attribute “hx-trigger” to any element. This will cause the defined AJAX call to be fired when the event is triggered.

Imagine we are still working on our example project with the ticket dashboard. We could add a trigger attribute to the main navigation ticket counter called “ticketCounterHasChanged”:

Take care to also add “from:body” because the event gets fired from there. Otherwise it won’t be detected properly.

When handling the request in the django view and rendering the HTML snippet, we can now add a custom header “HX-Trigger” to our response. HTMX will automatically detect the header and trigger all elements listening on this specific event — and the best thing: You can even trigger multiple signals!

Marrying django and HTMX

As always when trying to make django work with AJAX, you need to set the CSRF cookie. The django docs describe explicitly how to do it for jQuery, here is the snippet you need for django. Just put the following somewhere in your base.html.

View and Header

Having the CSRF protection set up this way, you can start implementing any view. Imagine, we have some custom logic we want to implement, like closing the ticket in our dashboard. In the following example we render a template and afterwards inject the custom header in the response.

Now, when we click to close the ticket the response contains our custom header which will trigger the open ticket badge in our main navigation to reload.

Photo by Benjamin Sharpe on Unsplash

Multiple Events

We created our example to have not one but two effects that should happen on closing a specific ticket apart from — well — closing it. We’d need to update the open ticket badge in the main navigation AND the to-do list within the sidebar. There is a neat solution for this as well. Just set the custom header to a dictionary and you can trigger as many events as you like.

Note, that the event is the key of the dictionary. The value can be used to pass data to the frontend. For our first event, we just pass a hyphen because we just don’t need it. For the second one we pass a variable containing any kind of data — as an example.

Utilising the header value

The possibility to add context data to your events opens up a lot of opportunities. Imagine, you want to inform the user about what just happened, like “This ticket was successfully closed”. You could pass this to a toaster and display a fancy message.

Here is an example how to set up the response:

Using MaterializeCSS and the passed data inside Javascript variable e:

It’s obvious that this is just one of many nice, generic and DRY use-cases for passing data like this to the frontend.

Photo by Seriously Low Carb on Unsplash

Drawbacks

Just to be clear: If you are building a fancy SPA with loads of user-interaction, do yourself a favour and use one of the big frameworks. But in many cases using the server-side-rendered django template and adding tiny bits of interaction will fully suffice for what needs to be done to meet the given acceptance criteria.

Furthermore, taking this path might give you a nice head-start but it’s a slippery slope. If your project grows (projects tend to grow or fail) you might end up with lots of HTMX spaghetti code to realise all your customers frontend wishes. So, beware that there is a good chance you’ll pay your easy-going starting phase triple at some later point in your project.

Wrap-up

As shown using HTMX not only makes your life easier and your application to require less code —but it also enables some unique possibilities to take your frontend even further.

A scenario where HTMX might be a good choice could be upgrading the django admin to add more convenience for the editors of your application, while the customers deal with a JS-built frontend.

Nevertheless, always consider your long-term goals for your project. After all, HTMX is more a helper than a proper framework!

--

--

Ronny Vedrilla
ambient-digital

Tech Evangelist and Senior Developer at Ambient in Cologne, Germany.