Ajax
The Drupal API behind in-place updates such as the Add another item button: an #ajax property, a PHP callback and JSON commands.
Ajax (Asynchronous JavaScript and XML) is a technique for changing part of a web page after it has loaded, by asking the server for new data in the background. Drupal packages it as the Ajax API: an event such as a click or a keystroke triggers a PHP callback, and the browser applies the returned markup or commands without a full refresh.
How it works in Drupal 11
The usual entry point is the #ajax property on a form element in the Form API. All of its keys are optional. Drupal's own documentation lists these and a few more:
callbackis the server-side function that handles the event.wrapperis the HTMLidof the area that receives the returned content.methodpicks the jQuery method used to place it;replaceWithis the default.eventis the browser event that fires the request. Drupal chooses one for each element type.progresssets the indicator, a throbber by default or a progress bar.
When an element carries #ajax, core attaches the core/drupal.ajax library for you. The callback receives the form and its state. It can return HTML or a render array, which goes into the wrapper, or an AjaxResponse object holding commands such as ReplaceCommand, HtmlCommand or RedirectCommand. The browser code lives in misc/ajax.js and builds on jQuery, which the drupal.ajax library lists as a dependency.
Drupal also offers shortcuts. A link with the class use-ajax loads through Ajax, and a submit button with use-ajax-submit submits that way. A text field with #autocomplete_route_name fetches its suggestions in the background.
Example
Editors meet Ajax whenever a field accepts an unlimited number of values. The Add another item button adds a new input without reloading the node form; its #ajax definition sits in WidgetBase. A developer building a similar interaction writes:
$form['preview'] = [
'#type' => 'textfield',
'#title' => $this->t('Format'),
'#ajax' => [
'callback' => '::updatePreview',
'event' => 'keyup',
'wrapper' => 'preview-output',
],
];
The page needs an element with the id preview-output, and updatePreview() returns the markup that replaces it.
Ajax and HTMX
The HTMX library became a core dependency in Drupal 11.2. Drupal 11.3.0 added PHP support for it: an Htmx class that builds HTMX attributes and headers, and a form builder that is aware of HTMX requests as it is of Ajax requests. The Ajax API stays. The core plan issue says core maintains both, and may deprecate #ajax, the Ajax commands and the Ajax library only once core is fully converted and contrib has clear conversion guidelines. It names no version. The Drupal.org HTMX guide offers a cookbook for rewriting Ajax code but gives no rule for new code. Both pages were checked on 26 October 2026.
Common mistakes
- A wrapper id that does not exist. The reply has nowhere to go. Give the target element the same
idaswrapper. - Expecting status messages with commands. They are added automatically only when you return markup into a wrapper. With an
AjaxResponseyou place them yourself. - Using a different URL for Ajax. Core recommends omitting
urlso that Drupal's content negotiation serves both the Ajax and the plain request.
For marketing and content teams
If a button spins and part of the page changes, that is Ajax. When such an interaction breaks, report which field or link you used and what you expected, plus any message in the browser console. A developer can then find its #ajax or use-ajax setting.
Sources
- Drupal API: Ajax API topic (core.api.php)
- Drupal.org: Ajax API
- Drupal core 11.4.10: AjaxResponse class
- Drupal core 11.4.10: core.libraries.yml (drupal.ajax)
- Drupal change record: Ajax subsystem now includes HTMX (11.3.0)
- Drupal.org issue: Gradually replace Drupal's AJAX system with HTMX
- MDN: AJAX
- Drupal.org: HTMX documentation
Questions about Ajax
Cite this definition
"Ajax." DXPR Drupal glossary, https://dxpr.com/hc/documentation/learn-drupal/drupal-glossary/ajax. Last updated October 26, 2026.