Before you upgrade, read Backwards incompatible changes in 1.2 below.
Welcome to djust 1.2!
These notes cover the new features, the backwards incompatible changes you should know about when upgrading from djust 1.1, and the security fixes in this release. When you're ready, follow the upgrade checklist.
djust 1.2 has three themes:
- The Rust template engine now behaves like Django's. It supports every built-in tag and filter, loads your own template tag libraries, and raises the errors Django raises. Templates that relied on djust being more lenient than Django will now fail. Most of the incompatible changes are in this area.
- Components are state. A component assigned on a view binds to that view, handles its own events, re-renders when a handler writes to it, and can patch just its own part of the page.
- Security hardening. 1.2.0 fixes eleven published advisories. Several of the fixes change a default, so read Security hardening that changes behaviour before you deploy.
djust 1.1.4 was released the same day with the same security fixes for the 1.1 line; see the 1.1.4 release notes. If you are coming from 0.9.x, read Upgrading to djust 1.0 first.
Python and Django compatibility
djust 1.2 supports Python 3.10, 3.11, 3.12, 3.13 and 3.14, and Django 4.2 (4.2.29 or later), 5.0, 5.1 and 5.2. Django 6.0 is not supported yet. This is the same range as djust 1.1.
The only new runtime dependency is packaging>=21, used by the update notice.
What's new in djust 1.2
Django template compatibility
djust renders LiveView templates, and optionally every template in your project through DjustTemplateBackend, with a Rust engine. In 1.2 that engine closes nearly all of its remaining gaps with Django:
- Every built-in tag and filter. All 25 of Django's built-in tags and 57 built-in filters are supported, including
{% autoescape %},{% filter %},{% ifchanged %},{% cycle %}with{% resetcycle %},{% querystring %},{% lorem %},{% debug %}and{% cache %}. - Your own template tags and filters.
{% load app_tags %}imports the Django template library and makes its tags and filters available to the Rust engine, in included and extended templates too. - Translations.
{% translate %},{% blocktranslate %}, the_("...")literal and thei18n,l10nandtzlibraries work. They run Django's own code, so catalogs, plural rules and escaping are Django's. - Lookups against the live object. A dotted lookup such as
{{ order.customer.get_full_name }}resolves one segment at a time against the Python object, as Django'sVariable._resolve_lookupdoes: attributes, properties, zero-argument methods and callables all work. - Values render as Django renders them.
{{ flag }}showsTrue,{{ items }}shows[1, 2], aware datetimes are converted to the current time zone, numbers follow the active locale, andDecimalvalues keep every digit.
The score to watch is Django's own template_tests suite run against DjustTemplateBackend: 1032 of the 1047 tests that reach a template engine pass (98.57%). When the scoreboard was first measured during the 1.2 cycle the figure was 43.55%. The remaining differences are listed in docs/TEMPLATE_COMPATIBILITY_LIMITS.md, and docs/TEMPLATE_BACKEND.md describes the backend.
Rendering also got cheaper. A render no longer copies the whole view state, and a {% for %} loop no longer copies it once per iteration, so the cost of a render depends on what the template reads rather than on everything the view holds (#2732, #2735, #2737). Large lists and querysets are no longer converted up front (#2717), and tags bridged from Django reuse one converted context per render (#2914).
Components are state
Three changes, each described by an ADR, make components behave like the rest of a view's state. See Components and the components guide.
- Class-level components bind per view (ADR-031).
nav = Tabs(active="overview")on a LiveView class gives each view instance its own bound component,self.nav, whose state isself.nav.state. Event handlers defined on the component class receive the bound component asself.{{ nav }}renders the component's template. - Component-scoped patches (ADR-032). When an event only changes one bound component and the page template uses it only as
{{ nav }}, djust renders that component alone and patches its subtree instead of re-rendering the page. - Plain components hold state (ADR-033).
self.rating.value = 5in a handler re-renders, and the value survives a reconnect.Component.event_attrs()writes typeddj-value-*attributes, so a handler receives4, not"4".Component(name="row-7")lets one handler serve several instances. Large components can narrow change detection withfingerprint_fields.
The component catalogue
djust.theming ships a browsable catalogue of the built-in components at /theme/components/. Each page shows a live preview with controls for the example's arguments, the view and template code to copy, a parameter table, events, accessibility notes, slots, and the source and stylesheet files that define the component. Moving between pages uses dj-navigate.
The same data is available from djust.theming.gallery.component_registry.describe_component(name), which also reports whether a component needs a script beyond djust's client. A project can wrap the catalogue in its own navigation by overriding the template djust_theming/catalogue/_document.html.
Bug capture and replay
Bug capture, introduced in 1.1, grows three pieces (Bug capture guide):
LiveView.time_travel_excluded_fieldsnames state that must never leave the server in a shared capture. The newdjust.V014check warns when a view withtime_travel_enabled = Trueholds a field that looks like personal data (an email address, a phone number) and doesn't exclude it.djust replay <capture>opens a capture in the browser, and--inspect/--diffprint it or diff its before and after state in the terminal.LIVEVIEW_CONFIG["bug_capture_store"]sends captures too large for a URL by reference instead.
Getting started
djust initadds djust to an existing Django project: it appends a marked settings block, replaces a stockasgi.pywith WebSocket routing, installsdjust,channelsanduvicorn[standard], and runsmanage.py check.--dry-runshows the changes. Files with uncommitted changes are left alone unless you pass--force. See Installation.djust newgenerates a themed starter page built fromdjust.themingcomponents, with a theme switcher.--baregives a one-button page instead. The generatedMakefileruns from the project's.venv, socd <name> && make devworks without activating it.- Update and security notices.
djust new,djust init, the development server andmanage.py check(asdjust.U001) print one line when a newer release exists or the installed version has a published advisory. See Update and security notices.
Minor features
Templates
DjustTemplateBackendraisesdjust.template.DjustTemplateSyntaxError, a subclass of Django'sTemplateSyntaxError, when a template is loaded, with Django'stemplate_debugdata for the debug page.- Importing
DjustTemplateBackendno longer imports the LiveView stack (Channels, presence, the WebSocket consumer).from djust import LiveViewis unchanged. - The new
djust.C016check warns when aDjangoTemplatesentry comes beforeDjustTemplateBackendinTEMPLATES, which hides every template djust could render, or when the admin is installed without aDjangoTemplatesentry. - The new
djust.T018check warns when a LiveView template references a variable the view never provides. See Type-safe template validation.
Events and the client
@debounceand@throttleare implemented in the client. The settings reach the browser on the mount frame, and a pending send is flushed ondj-submitand at page teardown.dj-mouseenteranddj-mouseleaveare event directives, with the platform's non-bubbling semantics. See Events.- The HTTP event fallback and
djust.call()find the CSRF token whenCSRF_COOKIE_NAME,CSRF_COOKIE_HTTPONLYorCSRF_USE_SESSIONSis set. djust injects<meta name="djust-csrf-cookie">and<meta name="djust-csrf-token">, andwindow.djust.csrfToken()returns the token. - Cmd, Ctrl, Shift and middle clicks on
dj-navigateanddj-patchlinks open a new tab, and the back button returns to the previous view. - A page restored from the browser's back/forward cache reconnects immediately.
- A
live_redirectflushes what the new view queued inmount(), such aspage_titleand flash messages.
Components
TableComponentgains filtering (filterable=True, and per column),aria-sorton sortable headers, a caption, a footer summary row and class hooks for each part of the table.ModalComponentaccepts afooter.- The theming
tabs,dropdownandmodalcomponents take their state from the view, so{% theme_tabs active=tabs.active %}drives them. theme_nav_group,theme_breadcrumbandtheme_nav_itemitems can setnavigateto render their link withdj-navigate.otp_inputworks; includedjust_components/otp-input.json the page.LiveComponent.trigger_update()re-renders the parent.
Audio
The opt-in AudioMixin and the {% djust_audio %} tag play short sound effects from a validated sound bank, activated by a user gesture. See Declarative audio.
Theming
- The theming types (
ThemePack,DesignSystem,LayoutStyleand the others) are importable fromdjust.theming. djust.themingprovides request-scoped helpers:get_active_pack,set_active_pack,get_active_mode,set_active_mode,reset_to_defaultsandget_theme_css_url.ThemeManagergainsset_pack()andreset().- A theme pack's icon style no longer restyles charts drawn by djust's components.
Testing
djust.testing.LiveComponentTestClienttests aLiveComponentwithout a parent view:LiveComponentTestClient(MyComponent).mount(**props), thensend_event(),get_state()andrender().LiveViewTestClient.mount()exercises the WebSocket mount, and records which branch it took inclient.via_websocket. See Testing LiveViews and the incompatible change below.
Observability and tooling
manage.py djust_observability_tokenprints the token the observability endpoints now require.manage.py djust_mcpsends it automatically.djust.V008accepts a return annotation such as-> stron a helper function or method defined in the same module as the view.
Backwards incompatible changes in 1.2
Most of the changes below make djust do what Django or the documentation already said it did. They are still breaking for code that depended on the old behaviour.
Security hardening that changes behaviour
Each of these closes a published advisory.
Built-in components escape their content. Every built-in component class, component template tag and Rust component renderer passes interpolated values through conditional_escape. HTML you pass into a content slot (a modal, card, sheet, popover, tab or accordion body, a header or footer, an icon) is shown as text unless it is marked safe.
Who is affected: anyone passing markup strings to built-in components.
What to do: pass mark_safe(...) or format_html(...) output, or another component's rendered output, for slots that should contain HTML. href and src values with a javascript:, vbscript: or non-image data: scheme now render as #; a value marked safe is passed through unchanged. The rich-text editor is the exception: its value is cleaned to an HTML allowlist that keeps formatting and removes scripts and event attributes.
djust admin enforces model permissions. DjustModelAdmin checks has_view_permission, has_add_permission, has_change_permission and has_delete_permission before mounting each page and again on every save, delete and delete_selected action. The default hooks now call user.has_perm() with the model's view_, add_, change_ and delete_ permission, as Django's ModelAdmin does. The index lists only the models the user has a permission on.
Who is affected: staff users who aren't superusers. Before 1.2, any active staff account had full access.
What to do: give those users or their groups the model permissions, or override the hooks on your DjustModelAdmin subclass.
The observability endpoints require a token. Besides DEBUG and a loopback client, a request to /_djust/observability/ must carry none of the proxy headers (X-Forwarded-For, Forwarded, X-Real-IP, X-Forwarded-Host, X-Forwarded-Proto) and must send the X-Djust-Observability-Token header. The token is derived from SECRET_KEY; set the DJUST_OBSERVABILITY_TOKEN environment variable to choose your own.
What to do: nothing if you use manage.py djust_mcp, which sends the header. For other tools, print the token with manage.py djust_observability_token and add the header.
Custom filters registered with is_safe=True keep unsafe input escaped. As in Django, the flag preserves safety; it doesn't grant it. A filter that returns a plain str built from user input is escaped even if it is registered is_safe=True.
What to do: a filter that produces markup must return mark_safe(...) or format_html(...) itself.
Custom tag return values are escaped. A simple_tag (or other custom tag handler) that returns a plain str is escaped, as Django escapes it. Return format_html(...) or mark_safe(...) for markup.
DataTable sorts, filters and groups only on declared columns. on_table_sort, on_table_filter, group-by and expression filters accept only keys listed in table_columns. A column is sortable unless it sets "sortable": False, and filterable only when it sets "filterable": True. table_default_sort is always accepted. Unknown column names are ignored.
What to do: add "filterable": True to every column users filter on, and list every column you sort or group by in table_columns.
Channel groups are joined after authorization. A LiveView joins its view, presence and db_notify groups only after check_permissions and the on_mount hooks pass, and those now run before on_view_mounted. A refused mount leaves every group.
Who is affected: code in on_view_mounted that assumed permission checks hadn't run yet.
Sticky children are re-authorized. A reused sticky {% live_render %} child re-runs its view and object permission checks on every parent render, and live_redirect carry-over re-checks object permissions. A child the user may no longer see is unmounted and the render fails as a fresh mount would.
Back-navigation state snapshots are bound to a digest of the session key. Snapshots issued by djust 1.1 fail verification once after the upgrade, and the view mounts fresh. No action is needed.
Resumable uploads belong to the session that started them. Resuming over the WebSocket and the HTTP upload-status endpoint answer only that session. Uploads started before the upgrade, or whose session key changed (for example at login), restart from the beginning.
Theme cookies are validated. A cookie naming an unregistered theme pack falls back to the session's pack, then the configured default. Layout names must match [A-Za-z0-9_-]{1,64}.
Templates are checked like Django's
These templates rendered on djust 1.1 and now raise, as they do on Django. Most raise TemplateSyntaxError when the template is loaded, even if the offending part is in a branch that never renders.
- An unknown filter name, or an unknown tag, even inside
{% if False %}. - A variable or attribute that starts with an underscore:
{{ _x }},{{ obj._private }},{{ obj.__class__ }}. - A filter with the wrong number of arguments (
{{ name|upper:"x" }}), or with two arguments. - A filter argument that can't be parsed or resolved, such as a misspelt variable name (
{{ text|wordwrap:widht }}). This raises at render time. - An empty
{{ }}, a duplicate{% block %}name, and malformed{% if %},{% url %},{% include %}and{{ }}expressions. {% cycle 'a' %}with a single value that isn't a named cycle.
These raise at render time:
{% for x in value %}wherevalueisn't iterable (for example an integer).Nonestill renders the{% empty %}block.first,last,random,escapeseq,safeseq,unordered_listandphone2numericon a value they can't iterate, index or lowercase (for example{{ 5|first }}), andget_digitanddivisiblebyon a date or datetime.{% url %}with a name or arguments that don't reverse raisesNoReverseMatch. Use{% url ... as var %}where a failed reverse is expected;varis then''.- A zero-argument method that raises during a lookup propagates the exception.
PermissionDeniedandHttp404raised while rendering give a 403 or 404 rather than a 500.
What to do: run your test suite and load every template. The error messages are Django's.
Templates render values the way Django does
Pages may look different after the upgrade:
- Time zones. With
USE_TZ = True, aware datetimes are converted to the current time zone before formatting, as Django does. djust 1.1 printed them in UTC. Naive datetimes are unchanged. - Localization. Numbers use the active language's decimal separator, and thousand separators when
USE_THOUSAND_SEPARATORis on. - Plain values.
{{ value }}rendersTrue,None,[1, 2],{'a': 1}and(1, 2)like Django. SetLIVEVIEW_CONFIG["django_value_repr"] = Falseto restore the 1.1 rendering while you update templates. - Deeper lookups. Templates can reach attributes, properties and methods that used to render empty. A custom tag handler that received a model from the context as a
dictnow receives an object, soctx["user"]["username"]must becomectx["user"].username. Names starting with_stay refused. - Callables in the context are called, as in Django, instead of rendering
None. |dateformats a full datetime instead of echoing it.{% cache %}skips its body on a cache hit, including any side effects in it.
Values sent to the browser
If client JavaScript reads LiveView state, check these:
- Booleans arrive as
trueandfalse, not1and0. Decimalvalues arrive as strings with every digit, not as floats.- Datetimes are formatted like
DjangoJSONEncoder: milliseconds, andZfor UTC.
Change detection and rendering
- In-place mutation re-renders.
self.items.append(x)orself.columns[key].append(card)in a handler now produces a patch. Previously it could be missed. Views that relied on the missed render will see more updates. - Lists of model instances aren't re-queried on every event. A
list[Model]assigned inmount()keeps its instances, so an unsaved edit to a row renders instead of being overwritten from the database. Callset_changed_keys("rows")after mutating an instance in place, and re-query explicitly when you want fresh rows. - The tick loop honours
_skip_render. Ahandle_tick()that setsself._skip_render = Trueno longer renders. A handler that sets both_skip_renderand a forced render now renders on every path. - URL keyword arguments are decoded. A LiveView mounted over the WebSocket receives
"Core UI", not"Core%20UI". Remove anyunquote()you added to work around this.
Components
- Class-level components are bound.
self.navis now aBoundComponent, soisinstance(self.nav, Tabs.State)isFalse; readself.nav.state. Attribute reads and writes are forwarded to the state. stateis a reservedComponentkeyword argument and raisesTypeError.- Built-in components emit typed
dj-value-*attributes instead ofdata-value. The client still readsdata-value. TableComponent.sort_by()takescolumn(wascolumn_key),TabsComponent.activate_tab()takestab=, and table row checkboxes carrydj-value-row-idinstead ofdata-row-id.{% modal %},{% confirm_dialog %},ExportDialogandBottomSheetdraw their backdrop as a separate.dj-scrimelement and no longer use an inlineonclick. Update any CSS that targeted the old structure.multi_selectcheckboxes also sendoption; a handler with a strict signature must accept it.- Sixteen components need a script from
djust_components/on the page (for examplecountdown.jsorscroll-spy.js).describe_component()and the catalogue say which.
The theme gallery moved
- The component storybook is now the component catalogue at
/theme/components/(was/theme/gallery/storybook/), and the theme gallery is at/theme/themes/(was/theme/gallery/). The old paths redirect permanently. - The older
djust.componentsgallery moved from/theme/components/to/theme/components-legacy/, without a redirect, because the catalogue now uses that path. - Python names were renamed to match:
theming.gallery.storybookistheming.gallery.catalogue,Storybook*ViewisComponents*View,{% storybook_preview %}and{% storybook_thumbnail %}are{% component_preview %}and{% component_thumbnail %}, URL namesstorybook*arecomponents*, and the pages' CSS prefixsb-isdc-.
Testing utilities
These come from real upgrades; expect a handful of test failures that are not app regressions.
LiveViewTestClient.mount()takes the WebSocket branch by default. It sets_websocket_session_idand the other attributes a live connection has, so code guarded byhasattr(self, "_websocket_session_id")(claiming a seat, presence tracking, subscriptions) now runs in tests. Each client gets its own synthetic session id. Callclient.mount(via_websocket=False)for a test about the HTTP prerender.send_event()raisesdjust.testing.NoHandlerFoundErrorfor an event with no handler, instead of returning{"success": False, ...}. Passraise_on_missing=Falseto get the old return value.- Anonymous presence for a session that has no key uses a per-view identity, so two test clients count as two presences instead of one.
System checks
manage.py check can report new messages after the upgrade. They are warnings or information, not errors, unless you run with --fail-level:
djust.T018warns about template variables the view never provides. It skips templates that use{% extends %}and says so in oneInfomessage; runmanage.py djust_typecheckfor those. Silence a name with{# djust_typecheck: noqa name #}, or the whole check withDJUST_CONFIG = {"suppress_checks": ["T018"]}.djust.C016warns about the order ofTEMPLATESentries.djust.V014warns about personal-data fields on views withtime_travel_enabled = Truethat aren't intime_travel_excluded_fields.djust.U001reports a newer release or a published advisory. It caches the advisory list for a day (in~/.cache/djust/updates.jsonunlessXDG_CACHE_HOMEorDJUST_CACHE_DIRis set), so after an advisory is corrected it can still report it until the cache expires. Delete the file to refresh it now. Turn the notice off withDJUST_CONFIG = {"update_check": False}orDJUST_NO_UPDATE_CHECK=1.djust.C013warns that the collectedclient.min.jsis older than the installed one. It fires after any upgrade until you runcollectstatic.djust.V008now accepts a primitive return annotation on a helper or method defined in the same module. An annotation on a helper imported from another module is still not read, so keep the# noqa: V008there.
Features removed in 1.2
LIVEVIEW_CONFIG["template_resolve_lazy"]is gone. Earlier 1.2 release candidates used it to switch off live-object lookups. Setting it now does nothing and raises no warning.- The static files
djust/security.js,djust/decorators.jsanddjust/js/pwa.jsare no longer shipped. djust's client never loaded them; remove any<script>tag or{% static %}reference to them. Thedj-offline="..."value form they implied is not supported. - The client-side
StateBusmodule was deleted. It was never exposed onwindow.djust.@client_stateand@optimisticremain inert decorators.
Deprecated features
djust 1.2 deprecates nothing new. The three symbols deprecated in 0.9.7, @event, LiveViewForm and the _legacy theming module, still work and still warn. See API stability and deprecations.
Security
djust 1.2.0 and 1.1.4 include fixes for the following advisories. Each advisory has the details and affected versions.
| Advisory | Area |
|---|---|
| GHSA-fccp-5h88-g34j | DataTable sorting, filtering and grouping |
| GHSA-jv2m-fcq9-94xf | djust admin (admin_ext) permissions |
| GHSA-c44q-w252-mr67 | Observability endpoints |
| GHSA-hc2m-gvfj-x6r3 | Built-in components |
| GHSA-r372-rrpw-5cgj | Built-in components |
| GHSA-j23m-jxwp-m3vq | Theming |
| GHSA-6q7c-hvpc-ff2q | Presence and channel groups |
| GHSA-5ffg-p52h-v2ph | Back-navigation state snapshots |
| GHSA-74vj-mpp4-45cg | Sticky {% live_render %} children |
| GHSA-7fcf-23mf-rhhm | Resumable uploads |
| GHSA-p9vp-rh5f-2cvq | Custom template filters (fixed in 1.2.0rc2) |
GHSA-3hp5-hxf8-qc48, the HTTP POST fallback skipping authorization, was fixed during the 1.2 cycle in 1.2.0rc8 and on the 1.1 line in 1.1.3.
The template engine work also closed several hardening gaps, listed in the CHANGELOG's Security sections:
- A key removed from a view's context stops rendering; before, its last value stayed in the Rust state.
- A
mark_safegrant no longer outlives the value it was granted for. - Password hashes and other sensitive model fields are withheld from templates and custom tag handlers on every path, including nested containers, the JIT serializer and the Rust queryset serializer.
- A template name can't escape its template directory (
{% include "../secret.txt" %}). - Component methods that change state (
mount,unmount,update,trigger_update) can't be called from a template.
Bug fixes
1.2 includes several hundred bug fixes. The main areas:
- Templates: inheritance and
{{ block.super }},{% regroup %}over objects, dictionary views and key types,Decimal, datetime and time-zone handling, and several crashes on unusual input. - Client and VDOM: scoped listeners are rebound or removed when their attributes change,
dj-keydown.enterbindings fire, and patches arriving during an event no longer force a full re-render. - Runtime: async work renders under the render lock,
start_asyncfrom adb_notify-released event runs, anduse_actorsviews mount their real template. - Components: modal, alert and badge dismiss, table sorting, pagination and selection, and buttons inside modals and sheets all reach the server.
- Admin: admin pages no longer return a 500 under the recommended
TEMPLATESsetup. - Scaffolding:
djust new --with-streaming,--from-schema,--with-authand--with-presencegenerate working projects. - Packaging:
collectstaticwithManifestStaticFilesStorage(and WhiteNoise) no longer fails on a missingclient.min.js.map.
The full list is in the 1.2.0rc1 to 1.2.0rc11 sections of the CHANGELOG. 1.2.0 itself is identical to 1.2.0rc11 apart from the version number.
Upgrading from 1.1
Upgrade and collect static files.
pip install "djust==1.2.0" python manage.py collectstatic --noinputdjust.C013stays untilcollectstatichas run.Run the checks.
python manage.py checkreports the newT018,C016,V014andU001messages. Fix or silence them; for templates using{% extends %}, also runpython manage.py djust_typecheck.Run your test suite, and expect these test-only changes:
- add
via_websocket=FalsetoLiveViewTestClient.mount()calls that test the HTTP prerender; - catch
NoHandlerFoundError(or passraise_on_missing=False) where a test sends an event with no handler.
- add
Load every template. Template errors that djust 1.1 ignored are now raised when a template is loaded or rendered. Rendering each page once, in a test or by hand, finds them.
Check what changed on the page: timestamps (now in local time), number formatting,
{{ }}output of booleans, lists and dicts, and any{% url %}whose reverse used to fail silently.Mark component HTML safe. Wrap markup passed to built-in component slots in
mark_safe()orformat_html(), and make custom filters and tags that produce markup return safe strings.Review permissions:
- grant model permissions to staff who use djust admin;
- add
"filterable": TruetoDataTablecolumns that users filter; - give observability clients other than
djust_mcptheX-Djust-Observability-Tokenheader.
Update client JavaScript and CSS that reads booleans, decimals or datetimes from state, or targets the modal backdrop,
data-valueordata-row-id.Update links and imports to the theme gallery and component catalogue if you used the old paths or
Storybook*names.Remove workarounds that 1.2 makes unnecessary:
unquote()on URL kwargs,# noqa: V008on same-module helpers annotated-> str, and anytemplate_resolve_lazysetting.
In-flight resumable uploads restart after the upgrade, and back-navigation snapshots from 1.1 are ignored once. Neither needs any action.
All changes in 1.2.0
The CHANGELOG.md entry for djust 1.2.0. Most of the changes are recorded under its 11 pre-releases: 1.2.0rc1, 1.2.0rc2, 1.2.0rc3, 1.2.0rc4, 1.2.0rc5, 1.2.0rc6, 1.2.0rc7, 1.2.0rc8, 1.2.0rc9, 1.2.0rc10, 1.2.0rc11.
The first stable release of the 1.2 line. The code is identical to 1.2.0rc11; see the 1.2.0rc1 to 1.2.0rc11 sections below for every change since 1.1, including the behaviour changes listed under rc11. 1.1.4 carries the same fixes for the 1.1 line.
Security
- This release and 1.1.4 include fixes for the following advisories; see each advisory for details:
- GHSA-fccp-5h88-g34j (DataTable)
- GHSA-jv2m-fcq9-94xf (admin_ext)
- GHSA-c44q-w252-mr67 (observability)
- GHSA-hc2m-gvfj-x6r3 and GHSA-r372-rrpw-5cgj (components)
- GHSA-j23m-jxwp-m3vq (theming)
- GHSA-6q7c-hvpc-ff2q (presence)
- GHSA-5ffg-p52h-v2ph (state snapshots)
- GHSA-74vj-mpp4-45cg (sticky live_render)
- GHSA-7fcf-23mf-rhhm (uploads)
- GHSA-p9vp-rh5f-2cvq (template filters; fixed in 1.2.0rc2, backported in 1.1.4)