Template tags¶
django-htmx comes with two template tags for rendering <script> tags, the first of which includes a vendored version of htmx.
The tags are available for both of Django’s built-in template engines:
For Django templates, use the
django_htmxtemplate library with{% load django_htmx %}.For Jinja, import the functions from
django_htmx.jinjaand add them to the environment.
All <script> tags are rendered with defer attribute to avoid blocking page rendering.
htmx_script¶
The htmx_script template tag renders script tags for:
A vendored version of htmx included in django-htmx. Two versions of htmx are vendored (htmx release notes):
htmx 2, the default — currently version 2.0.10.
htmx 4, currently in beta — version 4.0.0-beta6.
(There is no htmx 3—the project skipped from 2 to 4.)
Vendored htmx extensions, if requested with the
extensionsargument, covered below.django-htmx’s extension script, when
settings.DEBUGisTrue. This script adds an error handler for debugging HTTP errors, explained below.
Django templates¶
Load the library and use {% htmx_script %} in your <head> tag, typically in a base template:
{% load django_htmx %}
<!doctype html>
<html>
<head>
...
{% htmx_script %}
</head>
<body>
...
</body>
</html>
The default is to use a minified version of htmx.
Pass minified=False to render the non-minified version:
{% htmx_script minified=False %}
This may be useful when debugging htmx behaviour.
The default is to use htmx version 2.
Pass version=4 to render htmx version 4, currently in beta:
{% htmx_script version=4 %}
Pass extensions with a comma-separated string of names to also render script tags for vendored htmx extensions, matching the selected htmx version:
{% htmx_script version=4 extensions="hx-sse,hx-ws" %}
On Django 6.0+, the <script> tags will include the Content Security Policy (CSP) nonce, if it’s present in the context.
Jinja¶
First, load the tag function into the globals of your custom environment:
from jinja2 import Environment
from django_htmx.jinja import htmx_script
def environment(**options):
env = Environment(**options)
env.globals.update(
{
# ...
"htmx_script": htmx_script,
}
)
return env
Second, call the function in a variable in your <head> tag, typically in a base template:
{% load django_htmx %}
<!doctype html>
<html>
<head>
...
{{ htmx_script() }}
</head>
<body>
...
</body>
</html>
The default is to use a minified version of htmx.
Pass minified=False to render the non-minified version:
{{ htmx_script(minified=False) }}
This may be useful when debugging htmx behaviour.
The default is to use htmx version 2.
Pass version=4 to render htmx version 4, currently in beta:
{{ htmx_script(version=4) }}
Pass extensions with a comma-separated string or sequence of names to also render script tags for vendored htmx extensions, matching the selected htmx version:
{{ htmx_script(version=4, extensions=["hx-sse", "hx-ws"]) }}
To use a CSP nonce, pass it to the function as nonce:
{{ htmx_script(nonce=csp_nonce) }}
Vendored htmx extensions¶
django-htmx vendors some stable htmx extensions.
Extensions are named per htmx 4, where they’re bundled with htmx itself.
Some extensions are only available for htmx 4, as shown in the below table.
The extensions argument renders a script tag for each named extension, using the file appropriate for the selected htmx version.
Name |
Description |
htmx 2 |
htmx 4 |
|---|---|---|---|
|
Compatibility behaviours from htmx 2, such as old event names, easing migration. |
— |
|
|
Show the browser’s native loading indicator during requests. |
— |
|
|
Trigger file downloads, with progress events, instead of swaps. |
— |
|
|
Merging of |
||
|
Optimistic UI updates before the response arrives. |
— |
|
|
Preload responses for links and forms before they’re requested. |
||
|
Restores htmx 2’s |
Included in htmx 2 itself. |
|
|
Polling tags, letting servers skip swaps when content hasn’t changed.
Supported by the |
— |
|
|
Server-sent events (SSE). |
||
|
Target multiple elements with the same swap content. |
— |
|
|
|
— |
|
|
WebSockets. |
The htmx 2 extension files come from their standalone packages, with the linked names and versions. The htmx 4 extension files are bundled with htmx itself, so they always match the vendored htmx 4 version.
Refer to each extension’s documentation for usage, which can differ between htmx versions.
Notably, htmx 2 extensions need activating with the hx-ext attribute using their htmx 2 names, like hx-ext="sse", whilst htmx 4 extensions are active as soon as their script is loaded.
htmax¶
htmx 4 also ships htmax, a bundle of htmx plus its most popular extensions in a single file.
Pass extensions="htmax" to render the bundle in place of the plain htmx script:
{% htmx_script version=4 extensions="htmax" %}
Since htmax already bundles its extensions, the htmax name cannot be combined with other extension names, and it’s only available with htmx version 4.
django_htmx_script¶
The django_htmx_script template tag renders a script tag only for the django-htmx extension script (explained below), when settings.DEBUG is True.
Use it when you’re sourcing htmx from outside django-htmx.
Django templates¶
Load and use the template tag after your htmx <script> tag:
{% load django_htmx %}
<!doctype html>
<html>
<head>
...
<script src="{% static 'custom/htmx.min.js' %}" defer></script>
{% django_htmx_script %}
</head>
<body>
...
</body>
</html>
On Django 6.0+, the <script> tag will include the Content Security Policy (CSP) nonce, if it’s present in the context.
Jinja¶
First, load the tag function into the globals of your custom environment:
from jinja2 import Environment
from django_htmx.jinja import django_htmx_script, htmx_script
def environment(**options):
env = Environment(**options)
env.globals.update(
{
# ...
"django_htmx_script": django_htmx_script,
}
)
return env
Second, call the function in a variable in your <head> tag, typically in a base template:
{% load django_htmx %}
<!doctype html>
<html>
<head>
...
<script src="{{ static('custom/htmx.min.js') }}" defer></script>
{{ django_htmx_script() }}
</head>
<body>
...
</body>
</html>
To use a CSP nonce, pass it to the function as nonce:
{{ django_htmx_script(nonce=csp_nonce) }}
django-htmx extension script¶
This script, rendered by either of the above template tags when settings.DEBUG is True, extends htmx with an error handler.
htmx’s default behaviour when encountering an HTTP error is to discard the response content, which can make it hard to debug errors.
This script adds an error handler that detects responses with 400, 403, 404, and 500 status codes and replaces the page with their content. This change exposes Django’s default error responses, allowing you to debug as you would for a non-htmx request.
See the script in action in the “Error Demo” section of the example project.
See its source on GitHub.