# Wagtail 5.0 release notes

_May 2, 2023_

```{contents}
---
local:
depth: 1
---
```

## What's new

### Django 4.2 support

This release adds support for Django 4.2.

### Object usage information on deleting objects

On deleting a page, image, document or snippet, the confirmation screen now provides a summary of where the object is used, allowing users to see the effect that deletion will have elsewhere on the site. This also prevents objects from being deleted in cases where deletion would be blocked by an `on_delete=PROTECT` constraint. This feature was developed by Sage Abdullah.

### SVG image support

The image library can now be configured to allow uploading SVG images. These are handled by the `{% image %}` template tag as normal, with some limitations on image operations - for full details, see [](svg_images). This feature was developed by Joshua Munn, and sponsored by [YouGov](https://yougov.com/).

### Custom validation support for StreamField

Support for adding custom validation logic to StreamField blocks has been formalized and simplified. For most purposes, raising a `ValidationError` from the block's `clean` method is now sufficient; more complex behaviors (such as attaching errors to a specific child block) are possible through block-specific subclasses of `ValidationError`. For more details, see [](streamfield_validation). This feature was developed by Matt Westcott.

### Customizable SVG icons

Wagtail’s icon set is now fully updated, customizable, and extendable. Built-in icons are now based on the latest [FontAwesome](https://fontawesome.com/) visuals, with capabilities to both customize existing icons as well as add new ones. In particular, this includes:

 * A new `{% icon %}` icon template tag to reuse icons in custom templates.
 * A `register_icons` hook to register new icons and override existing ones.
 * Live documentation of all available icons in the styleguide, showcasing the icons available on the current site.
 * A list of [all built-in icons](icons) within our developer documentation.
 * Support for customizing icons for snippets via `SnippetViewSet.icon`.
 * Support for custom panel icons, with defaults, displayed for top-level editor panels.
 * New icons for StreamField blocks

For more details, see our new [icons documentation](icons).

This has been made possible thanks to a multi-year refactoring effort to migrate all icons to SVG. Thank you to all contributors who participated in this effort: Coen van der Kamp, LB (Ben) Johnston, Dan Braghis, Daniel Kirkham, Sage Abdullah, Thibaud Colas, Scott Cranfill, Storm Heg, Steve Steinwand, Jérôme Lebleu, Abayomi Victory.

### Accessibility checker improvements

The [built-in accessibility checker](authoring_accessible_content) has been updated with:

 * 5 more Axe rules enabled by default.
 * Sorting of checker results according to their position on the page.
 * Highlight styles to more easily identify elements with errors.
 * Configuration APIs in {class}`~wagtail.admin.userbar.AccessibilityItem` for simpler customization of the checks performed.

Those improvements were implemented by Albina Starykova as part of an [Outreachy internship](https://wagtail.org/blog/introducing-wagtails-new-accessibility-checker/), with support from mentors Thibaud Colas, Sage Abdullah, and Joshua Munn.

### Always-on minimap

Following its introduction in Wagtail 4.1, we have made several improvements to the page editor minimap:

 * It now stays opened until dismissed, so users can keep it expanded if desired.
 * Its "expanded" state is preserved when navigating between different views of the CMS.
 * The minimap and "Collapse all" button now appear next to side panels rather than underneath, so they can be used at any time.
 * Clicking any item reveals the minimap, with appropriate text for screen reader users.
 * Navigating to a collapsed section of the page will reveal this section.

Thank you to everyone who provided feedback on this new addition to the editor experience. Those changes were implemented by Thibaud Colas.

### Dark mode

Wagtail’s admin interface now supports dark mode. The new dark theme can be enabled in account preferences, as well as configuring permanent usage of the light theme, or following system preferences.

We hope this new theme will bring accessibility improvements for users who prefer light text on dark backgrounds, and energy usage efficiency improvements for users of OLED monitors. This feature was developed by Thibaud Colas, with designs from Ben Enright.

### Snippets parity with ModelAdmin

Continuing on recent improvements to snippets, we have made the following additions to how snippets can be customized in the admin interface:

 * Allow customizing the base URL and URL namespace for snippet views.
 * Allow customizing the default ordering and number of items per page for snippet listing views.
 * Allow admin templates for snippets to be overridden on a per-model or per-app basis.
 * Allow overriding the base queryset to be used in snippet `IndexView`.
 * Allow customizing the `search_fields` and search backend via SnippetViewSet.
 * Allow filters on snippet index views to be customized through the `list_filter` attribute.
 * Allow `panels` / `edit_handler` to be specified via `SnippetViewSet`.
 * Support for customizing icons for snippets via `SnippetViewSet.icon`.
 * Allow snippets to be registered into arbitrary admin menu items.

For more details, see [](wagtailsnippets_custom_admin_views).

Developed by Sage Abdullah, these features were implemented as part of [RFC 85: Snippets parity with ModelAdmin](https://github.com/wagtail/rfcs/pull/85). We will start the deprecation process of the ModelAdmin contrib package in the next feature release and publish it as a separate package for users who wish to continue using it. The ModelAdmin package will be removed in Wagtail 6.0.

### Other features

 * Add `WAGTAILIMAGES_EXTENSIONS` setting to restrict image uploads to specific file types (Aman Pandey, Ananjan-R)
 * Update user list column level to `Access level` to be easier to understand (Vallabh Tiwari)
 * Migrate `.button-longrunning` behavior to a Stimulus controller with support for custom label element & duration (Loveth Omokaro)
 * Implement new simplified userbar designs (Albina Starykova)
 * Add usage view for pages (Sage Abdullah)
 * Copy page form now updates the slug field dynamically with a slugified value on blur (Loveth Omokaro)
 * Ensure selected collection is kept when navigating from documents or images listings to add multiple views & upon upload (Aman Pandey, Bojan Mihelac)
 * Keep applied filters when downloading form submissions (Suyash Srivastava)
 * Messages added dynamically via JavaScript now have an icon to be consistent with those supplied in the page's HTML (Aman Pandey)
 * Switch lock/unlock side panel toggle to a switch, with more appropriate confirmation message status (Sage Abdullah)
 * Ensure that changed or cleared selection from choosers will dispatch a DOM `change` event (George Sakkis)
 * Add the ability to [disable model indexing](wagtailsearch_disable_indexing) by setting `search_fields = []` (Daniel Kirkham)
 * Enhance `wagtail.search.utils.parse_query_string` to allow inner single quotes for key/value parsing (Aman Pandey)
 * Add helpful properties to [`Locale`](locale_model_ref) for more convenient usage within templates, see [](i18n_basic_example) (Andy Babic)
 * Re-label "StreamField blocks" option in block picker to "Blocks" (Thibaud Colas)
 * Switch styleguide navigation to use panel components and minimap (Thibaud Colas)
 * Explicitly specify `MenuItem.name` for Snippets, Reports, and Settings menu items (Sage Abdullah)
 * Move the help text of fields and blocks directly below their label for easier reading (Thibaud Colas)
 * The select all checkbox in simple translation's submit translation page will now be in sync with other checkbox changes (Hanoon)
 * Revise alignment and spacing of form fields and sections (Thibaud Colas)
 * Update Wagtail’s type scale so StreamField block labels and field labels are the same size (Thibaud Colas)
 * Style comments as per page editor design, in side panel (Karl Hobley, Thibaud Colas)
 * ReferenceIndex modified to only index Wagtail-related models, and allow other models to be explicitly registered (Daniel Kirkham)

### Bug fixes

 * Ensure `label_format` on StructBlock gracefully handles missing variables (Aadi jindal)
 * Adopt a no-JavaScript and more accessible solution for the 'Reset to default' switch to Gravatar when editing user profile (Loveth Omokaro)
 * Ensure `Site.get_site_root_paths` works on cache backends that do not preserve Python objects (Jaap Roes)
 * Ignore right clicks on side panel resizer (Sage Abdullah)
 * Resize in the correct direction for RTL languages with the side panel resizer (Sage Abdullah)
 * Fix image uploads on storage backends that require file pointer to be at the start of the file (Matt Westcott)
 * Fix "Edit this page" missing from userbar (Satvik Vashisht)
 * No longer allow invalid duplicate site hostname creation as hostnames and domain names are a case insensitive (Coen van der Kamp)
 * Image and Document multiple upload update forms now correctly use the progress button (longrunning) behavior when clicked (Loveth Omokaro)
 * Prevent audit log report from failing on missing models (Andy Chosak)
 * Ensure that the privacy collection privacy edit button is styled as a button (Jatin Kumar)
 * Fix page/snippet cannot proceed a `GroupApprovalTask` if it's locked by someone outside of the group (Sage Abdullah)
 * Allow manual lock even if `WorkflowLock` is currently applied (Sage Abdullah)
 * Add missing log information for `wagtail.schedule.cancel` (Stefan Hammer)
 * Fix timezone activation leaking into subsequent requests in `require_admin_access()` (Stefan Hammer)
 * Fix dialog component's message to have rounded corners at the top side (Sam)
 * When multiple documents are uploaded and then subsequently updated, ensure that existing success messages are cleared correctly (Aman Pandey)
 * Prevent matches from unrelated models from leaking into SQLite FTS searches (Matt Westcott)
 * Prevent duplicate addition of StreamField blocks with the new block picker (Deepam Priyadarshi)
 * Enable partial search on images and documents index view where available (Mng)
 * Adopt a no-JavaScript and more accessible solution for option selection in reporting, using HTML only `radio` input fields (Mehul Aggarwal)
 * Ensure that document search results count shows the correct all matches, not the paginate total (Andy Chosak)
 * Fix radio and checkbox elements shrinking when using a long label (Sage Abdullah)
 * Fix select elements expanding beyond their container when using a long option label (Sage Abdullah)
 * Fix timezone handling of `TemplateResponse`s for users with a custom timezone (Stefan Hammer, Sage Abdullah)
 * Ensure TableBlock initialization correctly runs after load and its width is aligned with the parent panel (Dan Braghis)
 * Ensure that the JavaScript media files are loaded by default in Snippet index listings for date fields (Sage Abdullah)
 * Fix server-side caching of the icons sprite (Thibaud Colas)
 * Avoid showing scrollbars in the block picker unless necessary (Babitha Kumari)
 * Always show Add buttons, guide lines, Move up/down, Duplicate, Delete; in StreamField and Inline Panel (Thibaud Colas)
 * Make admin JS i18n endpoint accessible to non-authenticated users (Matt Westcott)
 * Autosize text area field will now correctly resize when switching between comments toggle states (Suyash Srivastava)
 * Fix incorrect API serialization for document `download_url` when `WAGTAILDOCS_SERVE_METHOD` is `direct` (Swojak-A)
 * Fix template configuration of snippets index results view (fidoriel, Sage Abdullah)
 * Prevent long preview mode names from making the select element overflow the side panel (Sage Abdullah)
 * When i18n is not enabled, avoid making a Locale query on every page view (Dan Braghis)
 * Fix initialization of commenting widgets within StreamField (Thibaud Colas)
 * Fix various regressions in the commenting UI (Thibaud Colas)
 * Prevent TableBlock from becoming uneditable after save (Sage Abdullah)
 * Correctly show the "new item" badge within menu sections previously dismissed (Sage Abdullah)
 * Fix side panel stuck in resize state when pointer is released outside the grip (Sage Abdullah)

### Documentation

 * Add code block to make it easier to understand contribution docs (Suyash Singh)
 * Fix broken formatting for MultiFieldPanel / FieldRowPanel permission kwarg docs (Matt Westcott)
 * Add helpful troubleshooting links and refine wording for getting started with development (Loveth Omokaro)
 * Ensure search autocomplete overlay on mobile does not overflow the viewport (Ayman Makroo)
 * Improve documentation for InlinePanel (Vallabh Tiwari)
 * Remove confusing `SettingsPanel` reference in the page editing `TabbedInterface` example as `SettingsPanel` no longer shows anything as of 4.1 (Kenny Wolf, Julian Bigler)
 * Add contributor guidelines for building [Stimulus Controllers](ui_guidelines_stimulus) (Thibaud Colas, Loveth Omokaro, LB (Ben) Johnston)
 * Fix typo in "Extending Draftail" documentation (Hans Kelson)
 * Clarify `ClusterableModel` requirements for using relations with `RevisionMixin`-enabled models (Sage Abdullah)
 * Add guide to making your first contribution (LB (Ben) Johnston)

### Maintenance

 * Removed features deprecated in Wagtail 3.0 and 4.0 (Matt Westcott)
 * Update djhtml (html formatting) library to v 1.5.2 (Loveth Omokaro)
 * Re-enable `strictPropertyInitialization` in tsconfig (Thibaud Colas)
 * Refactor accessibility checker userbar item (Albina Starykova)
 * Removed unused `Page.get_static_site_paths` method (Yosr Karoui)
 * Provisional Django 5.0 compatibility fixes (Sage Abdullah)
 * Add unit tests for `CollapseAll` and `MinimapItem` components (Albina Starykova)
 * Code quality fixes (GLEF1X)
 * Refactor image / document / snippet usage views into a shared generic view (Sage Abdullah)
 * Rename the Stimulus `AutoFieldController` to the less confusing `SubmitController` (Loveth Omokaro)
 * Replace `script` tags with `template` tag for image/document bulk uploads (Rishabh Kumar Bahukhandi)
 * Remove unneeded float styles on 404 page (Fabien Le Frapper)
 * Convert userbar implementation to TypeScript (Albina Starykova)
 * Migrate slug field behavior to a Stimulus controller and create new `SlugInput` widget (Loveth Omokaro)
 * Refactor `status` HTML usage to shared template tag (Aman Pandey, LB (Ben) Johnston, Himanshu Garg)
 * Add curlylint and update djhtml, semgrep versions in pre-commit config (Himanshu Garg)
 * Use shared header template for `ModelAdmin` and Snippets type index header (Aman Pandey)
 * Move models and forms for `wagtailsearch.Query` to `wagtail.contrib.search_promotions` (Karl Hobley)
 * Migrate `initErrorDetection` (tabs error counts) to a Stimulus Controller `w-count` (Aman Pandey)
 * Migrate `window.addMessage` behavior to a global event listener & Stimulus Controller approach with `w-messages` (Aman Pandey)
 * Update Algolia DocSearch to use new application and correct versioning setup (Thibaud Colas)
 * Move snippet choosers and model check registration to `SnippetViewSet.on_register()` (Sage Abdullah)
 * Remove unused snippets delete-multiple view (Sage Abdullah)
 * Improve performance of determining live page URLs across the admin interface using [`pageurl` template tag](performance_page_urls) (Satvik Vashisht)
 * Migrate `window.initSlugAutoPopulate` behavior to a Stimulus Controller `w-sync` (Loveth Omokaro)
 * Rename `status` classes to `w-status` to align with preferred CSS class naming conventions (Mansi Gundre)
 * Include wagtail-factories in `wagtail.test.utils` to avoid cross-dependency issues (Matt Westcott)
 * Fix search tests to correctly reflect behavior of search backends other than the fallback backend (Matt Westcott)
 * Migrate select all checkbox in simple translation's submit translation page to Stimulus controller `w-bulk`, remove inline script usage (Hanoon)
 * Refactor `SnippetViewSet` to extend `ModelViewSet` (Sage Abdullah)
 * Migrate initDismissibles behavior to a Stimulus controller `w-disimissible` (Loveth Omokaro)
 * Replace jQuery autosize v3 with Stimulus `w-autosize` controller using autosize npm package v6 (Suyash Srivastava)
 * Update `w-action` controller to support a click method (Suyash Srivastava)
 * Migrate the site settings switcher select from jQuery to a refined version of the `w-action` controller usage (Aadi jindal, LB (Ben) Johnston)
 * Always use expanded Sass output so CSS processing is identical in development and production builds (Thibaud Colas)
 * Refactor admin color palette to semantic, theme-agnostic design tokens (Thibaud Colas)


## Upgrade considerations

### Removal of deprecated features

The following features deprecated in Wagtail 3.0 have been fully removed. See [Wagtail 3.0 release notes](/releases/3.0) for details on these changes, including how to remove usage of these features:

* The modules `wagtail.core`, `wagtail.tests`, `wagtail.admin.edit_handlers` and `wagtail.contrib.forms.edit_handlers` are removed.
* The field panel classes `StreamFieldPanel`, `RichTextFieldPanel`, `ImageChooserPanel`, `DocumentChooserPanel` and `SnippetChooserPanel` are removed.
* StreamField definitions must include `use_json_field=True` (except migrations created before Wagtail 5.0).
* The `BASE_URL` setting is no longer recognized.
* The `ModelAdmin.get_form_fields_exclude` method is no longer passed a `request` argument.
* The `ModelAdmin.get_edit_handler` method is no longer passed a `request` or `instance` argument.
* The `widget_overrides`, `required_fields`, `required_formsets`, `bind_to`, `render_as_object` and `render_as_field` methods on `Panel` (previously `EditHandler`) are removed.

The following features deprecated in Wagtail 4.0 have been fully removed. See [Wagtail 4.0 release notes](/releases/4.0) for details on these changes, including how to remove usage of these features:

* The `wagtail.contrib.settings.models.BaseSetting` class is removed.
* The `Page.get_latest_revision_as_page` method is removed.
* The `page` and `page_id` properties and `as_page_object` method on `Revision` are removed.
* The JavaScript functions `createPageChooser`, `createSnippetChooser`, `createDocumentChooser` and `createImageChooser` are removed.
* The `wagtail.contrib.modeladmin.menus.SubMenu` class is removed.
* Subclasses of `wagtail.contrib.modeladmin.helpers.AdminURLHelper` are now required to accept a `base_url_path` keyword argument on the constructor.
* The `wagtail.admin.widgets.chooser.AdminChooser` class is removed.
* The `wagtail.snippets.views.snippets.get_snippet_edit_handler` function is removed.

### Dropped support for Django 4.0

Django 4.0 reached end of life on 1st April 2023 and is no longer supported by Wagtail. Django 3.2 (LTS) is still supported until April 2024.

### Elasticsearch backend no longer performs partial matching on `search`

The `search` method on pages, images and documents, and on the backend object returned by `wagtail.search.backends.get_search_backend()`, no longer performs partial word matching when the Elasticsearch backend is in use. Previously, a search query such as `Page.objects.search("cat")` would return results containing the word "caterpillar", while `Page.objects.search("cat", partial_match=False)` would only return results for the exact word "cat". The `search` method now always performs exact word matches, and the `partial_match` argument has no effect. This change makes the Elasticsearch backend consistent with the database-backed full-text search backends.

To revert to the previous partial word matching behavior, use the `autocomplete` method instead - for example, `Page.objects.autocomplete("cat")`. It may also be necessary to add an [](wagtailsearch_index_autocompletefield) entry for the relevant fields on the model's `search_fields` definition, as the old `SearchField("some_field", partial_match=True)` format is no longer supported.

The `partial_match` argument on `search` and `SearchField` is now deprecated, and should be removed from your code; it will be dropped entirely in Wagtail 6.

### ReferenceIndex no longer tracks models used outside of Wagtail

When introduced in Wagtail 4.1, the `ReferenceIndex` model recorded references across all of a project's models by default. The default set of models being indexed has now been changed to only those used within the Wagtail admin, specifically:

* all Page types
* Images
* Documents
* models registered as Snippets
* models registered with ModelAdmin

This change will remove the impact of the indexing on non-Wagtail apps and models.

If you have models that still require reference indexing, and which are not registered as snippets or with ModelAdmin, you will need to explicitly register them within your app's `AppConfig.ready()` method. See [Reference Index](registering_a_model_for_indexing) for further details.

The use of `wagtail_reference_index_ignore` to prevent indexing of models is unchanged, but in many cases it may no longer be necessary.

It is recommended that the `rebuild_references_index` management command is run after the upgrade to remove any unnecessary records.

### `Page.get_static_site_paths` method removed

The undocumented `Page.get_static_site_paths` method (which returns a generator of URL paths for use by static site generator packages) has been removed. Packages relying on this functionality should provide their own fallback implementation.

(wagtailsearch_query_migration)=

### `wagtailsearch.Query` has moved to `wagtail.contrib.search_promotions`

The `wagtailsearch.Query` model has been moved from the `search` application to the contrib application `wagtail.contrib.search_promotions`.
All imports will need to be updated and migrations will need to be run via a management command, some imports will still work with a warning until a future version.

To continue using the `Query` model, you must also add the `wagtail.contrib.search_promotions` application to your project's `INSTALLED_APPS` setting.

#### Migration command

If you have daily hits records in the `wagtailsearch.Query` you can run the management command to move these records to the new location.

```sh
./manage.py copy_daily_hits_from_wagtailsearch
```

#### Managing stored search queries

The `search_garbage_collect` command used to remove old stored search queries and daily hits has been moved to [`searchpromotions_garbage_collect`](searchpromotions_garbage_collect).

#### Import updates

| **Import**    | **Old import**                               | **New import**                                                  |
| ------------- | -------------------------------------------- | --------------------------------------------------------------- |
| `Query` Model | `from wagtail.search.models import Query`    | `from wagtail.contrib.search_promotions.models import Query`    |
| `QueryForm`   | `from wagtail.search.forms import QueryForm` | `from wagtail.contrib.search_promotions.forms import QueryForm` |

### Changes to header CSS classes in `ModelAdmin` templates

If there are custom styles in place for the `ModelAdmin`'s header content or more complex template overrides in use, there are a few changes for the following classes to be aware of.

| **Content**                      | **Old classes**       | **New classes** |
| -------------------------------- | --------------------- | --------------- |
| Heading & search (contains `h1`) | `.left.header-left`   | `.left`         |
| Action buttons (`header_extra`)  | `.right.header-right` | `.right`        |

### Slug field auto-cleaning now relies on data attributes

The slug field JavaScript behavior was previously attached to any field with an ID of `id_slug`, this has now changed to be any field with the appropriate Stimulus data attributes.

If using a custom edit handler or set of panels for page models, the correct widget will now need to be used for these data attributes to be included. This widget will use the `WAGTAIL_ALLOW_UNICODE_SLUGS` Django setting.

```python
from wagtail.admin.widgets.slug import SlugInput
# ... other imports

class MyPage(Page):
    promote_panels = [
        FieldPanel("slug", widget=SlugInput),
        # ... other panels
    ]
```

Additionally, the slug behavior can be attached to any field easily by including the following attributes in HTML or via Django's widget `attrs`.

```html
<input
    type="text"
    name="slug"
    data-controller="w-slug"
    data-action="blur->w-slug#slugify"
/>
```

To allow unicode values, add the data attribute value;

```html
<input
    type="text"
    name="slug"
    data-controller="w-slug"
    data-action="blur->w-slug#slugify"
    data-w-slug-allow-unicode-value="true"
/>
```

### Changes to title / slug field synchronization

The mechanism for synchronizing the slug field with the page title has changed, and is no longer hard-coded to activate on fields named 'title'. Notably, this change affects page panel definitions that use `FieldPanel("title")` directly (rather than the convention of extending `Page.content_panels`), as well as non-page models such as snippets.

To assist in upgrading these definitions, Wagtail 5.0.2 provides a new [](title_field_panel) class to be used in place of `FieldPanel("title")`. For example:

```python
from wagtail.admin.panels import FieldPanel, MultiFieldPanel

    # ...
    content_panels = [
        MultiFieldPanel([
            FieldPanel("title"),
            FieldPanel("subtitle"),
        ]),
    ]
```

should become:

```python
from wagtail.admin.panels import FieldPanel, MultiFieldPanel, TitleFieldPanel

    # ...
    content_panels = [
        MultiFieldPanel([
            TitleFieldPanel("title"),
            FieldPanel("subtitle"),
        ]),
    ]
```

If you have made deeper customizations to this behavior, or are unable to upgrade to Wagtail 5.0.2 or above, please read on as you may need to make some changes to adopt the new approach.

The title field will sync its value with the slug field on Pages if the Page is not published and the slug has not been manually changed. This JavaScript behavior previously attached to any field with an ID of `id_title`; this has now changed to be any field with the appropriate Stimulus data attributes.

There is a new Stimulus controller `w-sync` which allows any field to change one or more other fields when its value changes, the other field in this case will be the slug field (`w-slug`) with the id `id_slug`.

If you need to hook into this behavior, the new approach will now correctly dispatch `change` events on the slug field. Alternatively, you can modify the data attributes on the fields to adjust this behavior.

To adjust the target field (the one to be updated), you cam modify `"data-w-sync-target-value"`, the default being `"body:not(.page-is-live) [data-edit-form] #id_slug"` (find the field with id `id_slug` when the page is not live).

To adjust what triggers the initial check (to see if the fields should be in sync), or the trigger the sync, you can use the Stimulus `data-action` attributes.

```html
<input
    id="id_title"
    type="text"
    name="title"
    data-controller="w-sync"
    data-action="focus->w-sync#check blur->w-sync#apply change->w-sync#apply"
    data-w-sync-target-value="body:not(.page-is-live) #some_other_slug"
/>
```

Above we have adjusted these attributes to add a 'change' event listener to trigger the sync and also adjusted to look for a field with `some_other_slug` instead.

### Auto height/size text area widget now relies on data attributes

If you are using the `wagtail.admin.widgets.AdminAutoHeightTextInput` only, this change will have no impact when upgrading. However, if you are relying on the global `autosize` function at `window.autosize` on the client, this will no longer work.

It is recommended that the `AdminAutoHeightTextInput` widget be used instead. You can also adopt the `data-controller` attribute and this will now function as before. Alternatively, you can simply add the required Stimulus data controller attribute as shown below.

**Old syntax**

```html
<textarea id="story" name="story">It was a dark and stormy night...</textarea>
<script>window.autosize($('story'));</script>
```

**New syntax**

```html
<textarea name="story" data-controller="w-autosize">It was a dark and stormy night...</textarea>
```

There are no additional data attributes supported at this time.

### Progress button (`button-longrunning`) now relies on data attributes

The `button-longrunning` class usage has been updated to use the newly adopted Stimulus approach, the previous data attributes will be deprecated in a future release.

If using the old approach, ensure any HTML templates are updated to the new approach before the next major release.

**Old syntax**

```html+django
<button type="submit" class="button action-save button-longrunning" data-clicked-text="{% trans 'Creating…' %}">
  {% icon name="spinner" %}
  <em>{% trans 'Create' %}</em>
</button>
```

**New syntax**

Minimum required attributes are `data-controller` and a `data-action`.

```html+django
<button type="submit" class="button action-save button-longrunning" data-controller="w-progress" data-action="w-progress#activate" data-w-progress-active-value="{% trans 'Creating…' %}">
  {% icon name="spinner" %}
  <em data-w-progress-target="label">{% trans 'Create' %}</em>
</button>
```

#### Examples of additional capabilities

Stimulus [targets](https://stimulus.hotwired.dev/reference/targets) and [actions](https://stimulus.hotwired.dev/reference/actions) can be leveraged to revise the behavior via data attributes.

* `<button ... data-w-progress-duration-value="500" ...>` - custom duration can be declared on the element
* `<button ... class="custom-button" data-w-progress-active-class="custom-button--busy" ...>` - custom 'active' class to replace the default `button-longrunning-active` (must be a single string without spaces)
* `<button ... ><strong data-w-progress-target="label">{% trans 'Create' %}</strong></button>` - any element can be the button label (not just `em`)
* `<button ... data-action="w-progress#activate focus->w-progress#activate" ...>` - any event can be used to trigger the in progress behavior
* `<button ... data-action="w-progress#activate:once" ...>` - only trigger the progress behavior once
* `<button ... data-action="readystatechange@document->w-progress#activate:once" data-w-progress-duration-value="5000" disabled ...>` - disabled on load (once JS starts) and becomes enabled after 5s duration


### JavaScript `window.addMessages` replaced with event dispatching

The undocumented `window.addMessage` function is no longer available and will throw an error if called, if similar functionality is required use DOM Event dispatching instead as follows.

```javascript
// old
window.addMessage('success', 'Content has updated');
```

```javascript
// new
document.dispatchEvent(
    new CustomEvent('w-messages:add', {
        detail: { text: 'Content has updated', type: 'success' },
    }),
);
// new (clearing existing messages before adding a new one)
document.dispatchEvent(
    new CustomEvent('w-messages:add', {
        detail: {
            clear: true,
            text: 'All content has updated',
            type: 'success',
        },
    }),
);
// message types 'success', 'error', 'warning' are supported
```

Note that this event name may change in the future and this functionality is still not officially supported.

### Changes to StreamField `ValidationError` classes

The client-side handling of StreamField validation errors has been updated. The JavaScript classes `StreamBlockValidationError`, `ListBlockValidationError`, `StructBlockValidationError` and `TypedTableBlockValidationError` have been removed, and the corresponding Python classes can no longer be serialized using Telepath. Instead, the `setError` methods on client-side block objects now accept a plain JSON representation of the error, obtained from the `as_json_data` method on the Python class. Custom JavaScript code that works with these objects must be updated accordingly.

Additionally, the Python `StreamBlockValidationError`, `ListBlockValidationError`, `StructBlockValidationError` and `TypedTableBlockValidationError` classes no longer provide a `params` dict with `block_errors` and `non_block_errors` items; these are now available as the attributes `block_errors` and `non_block_errors` on the exception itself (or `cell_errors` and `non_block_errors` in the case of `TypedTableBlockValidationError`).

### Snippets `delete-multiple` view removed

The ability to remove multiple snippet instances from the `DeleteView` and the undocumented `wagtailsnippets_{app_label}_{model_name}:delete-multiple` URL pattern have been removed. The view's functionality has been replaced by the delete action of the bulk actions feature introduced in Wagtail 4.0.

The delete bulk action view now also calls the `{before,after}_delete_snippet` hooks, in addition to the `{before,after}_bulk_action` hooks.

If you have customized the `IndexView` and/or `DeleteView` views in a `SnippetViewSet` subclass, make sure that the `delete_multiple_url_name` attribute is renamed to `delete_url_name`.

### Snippets index views template name changed

The template name for the index view of a snippet model has changed from `wagtailsnippets/snippets/type_index.html` and `wagtailsnippets/snippets/results.html` to `wagtailsnippets/snippets/index.html` and `wagtailsnippets/snippets/index_results.html`. In addition, the model index view that lists the snippet types now looks for the template `wagtailsnippets/snippets/model_index.html` before resorting to the generic index template. If you have customized these templates, make sure to update them accordingly.

### `status` classes are now `w-status`

Please update any custom styling or usage within the admin when working with status tags to the following new classes.

| Old                 | New                  |
| ------------------- | -------------------- |
| `status-tag`        | `w-status`           |
| `primary`           | `w-status--primary`  |
| `disabled`          | `w-status--disabled` |
| `status-tag--label` | `w-status--label`    |

Note that a new template tag has been built for usage within the admin that may make it easier to generate status tags.

```html+django
{% load wagtailadmin_tags %}
{% status "live" url="/test-url/" title=trans_title hidden_label=trans_hidden_label classname="w-status--primary" attrs='target="_blank" rel="noreferrer"' %}
{% status status_label classname="w-status--primary" %}
```

### Deprecated icon font

The Wagtail icon font has been deprecated and will be removed in a future release, as it is now unused in Wagtail itself. There are no changes to make for any icons usage via dedicated APIs such as `icon` class properties. Any direct icon font usage needs to be converted to SVG icons instead, as documented in our [icons overview](icons).

To check whether your project uses the icon font, check for occurrences of:

* Loading of the `wagtail.woff` font file.
* Usage of `font-family: wagtail` in CSS.
* `icon-<name>` CSS classes outside of SVG elements.

### Deprecated icons

The following icons are unused in Wagtail itself and will be removed in a future release. If you are using any of these icons, please replace them with an alternative (see our full [list of icons](icons)), or re-add the icon to your own project.

| Icon name            | Alternative                  |
| -------------------- | ---------------------------- |
| `angle-double-left`  | `arrow-left`                 |
| `angle-double-right` | `arrow-right`                |
| `arrow-down-big`     | `arrow-down`                 |
| `arrow-up-big`       | `arrow-up`                   |
| `arrows-up-down`     | `order`                      |
| `chain-broken`       | `link`                       |
| `chevron-down`       | `arrow-down` (identical)     |
| `dots-vertical`      | `dots-horizontal`            |
| `download-alt`       | `download` (identical)       |
| `duplicate`          | `copy` (identical)           |
| `ellipsis-v`         | `dots-horizontal`            |
| `horizontalrule`     | `minus`                      |
| `repeat`             | `rotate`                     |
| `reset`              | `rotate`                     |
| `tick`               | `check` (identical)          |
| `undo`               | `rotate`                     |
| `uni52`              | `folder-inverse` (identical) |
| `wagtail-inverse`    | `wagtail-icon`               |

### Snippets `get_admin_url_namespace()` and `get_admin_base_path()` moved to `SnippetViewSet`

The undocumented `get_admin_url_namespace()` and `get_admin_base_path()` methods that were set on snippet models at runtime have been moved to the {class}`~wagtail.snippets.views.snippets.SnippetViewSet` class. If you use these methods, you could access them via {meth}`SnippetModel.snippet_viewset.get_admin_url_namespace() <wagtail.snippets.views.snippets.SnippetViewSet.get_admin_url_namespace>` and {meth}`SnippetModel.snippet_viewset.get_admin_base_path() <wagtail.snippets.views.snippets.SnippetViewSet.get_admin_base_path>`, respectively.

### Snippets `get_usage()` and `usage_url()` methods removed

The undocumented `get_usage()` and `usage_url()` methods that were set on snippet models at runtime have been removed. Calls to the `get_usage()` method can be replaced with `wagtail.models.ReferenceIndex.get_grouped_references_to(object)`. The `usage_url()` method does not have a direct replacement, but the URL name can be retrieved via {meth}`SnippetModel.snippet_viewset.get_url_name("usage") <wagtail.admin.viewsets.base.ViewSet.get_url_name>`, which can be used to construct the URL with {func}`~django.urls.reverse`.
