Quickstart
Here's how you integrate live components:
- Install
livecomponents. - Modify Django settings.
- Modify base HTML template.
- Modify project
urls.pyto include live components.
Installation
pip3 install git+https://github.com/om-proptech/livecomponents@...SHA1.HERE...
Django settings
Add to installed apps following packages:
INSTALLED_APPS = [
# ...
"django_components",
"django_components.safer_staticfiles", # replaces django.contrib.staticfiles
"django_htmx",
"livecomponents",
# ...
]
Add HTMX middleware:
MIDDLEWARE = [
# ...
"django_htmx.middleware.HtmxMiddleware",
# ...
]
Add template loader django_components.template_loader.Loader
so that component templates are found, e.g.:
TEMPLATES = [
{
# ...
"OPTIONS": {
# ...
"loaders": [
(
"django.template.loaders.cached.Loader",
[
# ...
"django_components.template_loader.Loader",
],
),
],
},
},
]
Add component dirs for to static files:
# Static files (CSS, JavaScript, Images)
STATICFILES_DIRS = [
# To load django-components specific to myapp
BASE_DIR / "app_one" / "components",
BASE_DIR / "app_two" / "components",
]
You can also configure live components with the LIVECOMPONENTS settings dictionary. See the "Configuration" section for more details.
Base template
There, we need support for HTMX and Live Components:
{% load ... component_tags django_htmx livecomponents %}
<head>
<!-- Configure HTMX. See https://htmx.org/docs/#config -->
<meta name="htmx-config" content='{"defaultSwapStyle":"none","allowNestedOobSwaps":false}'>
<!-- HTMX and plugins -->
<script src="https://unpkg.com/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha256-YCMa5rqds4JesVomESLV9VkhxNU7Zr9jfcGLTuJ8efk=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/htmx-ext-json-enc@2.0.2/json-enc.js" integrity="sha256-n+FPqu23kscMGH4hmy2Ocv7ZKJE3UgXa2d/v4Y2azOo=" crossorigin="anonymous"></script>
<script src="https://unpkg.com/htmx-ext-alpine-morph@2.0.1/alpine-morph.js" integrity="sha256-diqH7MmPdlWLfWOEw3QAq2HlqxYmGWy30JP864nBO2c=" crossorigin="anonymous"></script>
<!-- Alpine Plugins -->
<script defer src="https://unpkg.com/@alpinejs/morph@3.15.0/dist/cdn.min.js" integrity="sha256-yc4QYrkTmE2o9PYBjxsweN9Z28PQ3PSozmsuzd4So5w=" crossorigin="anonymous"></script>
<!-- Alpine Core -->
<script defer src="https://unpkg.com/alpinejs@3.15.0/dist/cdn.min.js" integrity="sha256-4EHxtjnR5rL8JzbY12OKQJr81ESm7JBEb49ORPo29AY=" crossorigin="anonymous"></script>
{% django_htmx_script %}
{% component_css_dependencies %}
{% livecomponents_session_id as LIVECOMPONENTS_SESSION_ID %}
<script>
// Optionally, clear the session on page unload.
//
// Firefox does not support keepalive fetches, so we need to use a workaround.
// See https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon
// and https://bugzilla.mozilla.org/show_bug.cgi?id=1342484
const fetchUrl = "{% url 'livecomponents:clear-session' %}?session_id={{ LIVECOMPONENTS_SESSION_ID }}";
const csrfmiddlewaretoken = "{{ csrf_token }}";
window.addEventListener("beforeunload", function () {
navigator.sendBeacon(fetchUrl, new URLSearchParams({csrfmiddlewaretoken}))
});
// Alternatively, use a regular fetch if you don't care about the issue above.
// window.addEventListener("beforeunload", function () {
// fetch(fetchUrl, {
// keepalive: true,
// method: "POST",
// headers: {"X-CSRFToken": csrfmiddlewaretoken}
// });
// });
</script>
...
</head>
<body hx-ext="alpine-morph, json-enc" hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
...
{% component_js_dependencies %}
</body>
<html>
Project urls.py
from django.urls import path, include
urlpatterns = [
# ...
path("livecomponents/", include("livecomponents.urls")),
# ...
]
Create new component
There is a management command to create new component:
./manage.py createlivecomponent <app_name> <directory/component_name>
The command with create a "components" subdirectory in the app directory and create a new component, consisting of one Python, and one HTML file.
Make sure that your STATICFILES_DIRS setting includes the "components" directory of the app.
Optionally, you can pass a --stateless flag to create a stateless component.
Disposable Redis server
live components depends on a local Redis server, at least by default. For a quick throw-away local Redis server, this command could be of use:
docker run --rm -d -p 127.0.0.1:6379:6379 redis:latest