First thing first what is HTMX partial rendering?. In a simple term the partial HTML rendering means that whenever HTMX makes the request to backend server you need to send the part of the HTML instead of the full website. But what will happen if the user just trying to load the partial render URL directly in the browser? You know that will lead to user will see part of the HTML in browser instead of full web application.
How the problem look like?
See the code that produce the above problem. User clicks the button and server renders a part of the HTML.
path("button/1", views.button_one, name="button1")
def button_one(request):
return render(request, "button1.html")
<!-- button1.html -->
{% extends "base.html" %}
{% block content %}Button One Response{% endblock content %}
Now imagine a user try to load the button/1/
directly in the browser instead of clicking it using HTMX. The browser will display the “Button One Response” instead of base.html combine response right?
How to avoid the above problem?
We can solve that by using template inheritance. Whenever HTMX makes the Ajax request to the server it includes a HTTP header. We can use that HTTP header to identify whether the request comes from the HTMX or the user try to load it directly.
def button_one(request):
base_template = "base.html"
if request.META["HX-Request"]:
base_template = "partial.html"
return render(request, "button1.html", {"base_template": base_template)
<!-- button1.html -->
{% extends base_template %}
{% block content %}Button One Response{% endblock content %}
<!-- partial.html -->
{% block content %}{ endblock content %}
Conclusion
With above code you can solve the partial rendering when the user try to load the URL directly. If user try to load directly then full HTML will return to the frontend. And likewise if the user tries to load using HTMX then only the partial template will return to the frontend.
This technique can be used with any of the backend framework not only for Python based application. If you are using django-htmx package then you can easily do that by
if bool(request.htmx):
base_template = "partial.html"