Ajax

The Drupal API behind in-place updates such as the Add another item button: an #ajax property, a PHP callback and JSON commands.

Learn DrupalDrupal glossary Last updated

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:

  • callback is the server-side function that handles the event.
  • wrapper is the HTML id of the area that receives the returned content.
  • method picks the jQuery method used to place it; replaceWith is the default.
  • event is the browser event that fires the request. Drupal chooses one for each element type.
  • progress sets 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 id as wrapper.
  • Expecting status messages with commands. They are added automatically only when you return markup into a wrapper. With an AjaxResponse you place them yourself.
  • Using a different URL for Ajax. Core recommends omitting url so 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

Questions about Ajax

No. The name is historical. Drupal's AjaxResponse class extends Symfony's JsonResponse, so the server answers with JSON that the browser script applies to the page. The Ajax library also depends on jQuery.

Not as of 26 October 2026. Drupal 11.3.0 added PHP support for HTMX beside it, and the plan issue says #ajax and the Ajax commands may be deprecated only once core is fully converted and contrib has conversion guidelines. No date is set. Existing Ajax code keeps working.

Add the class use-ajax to the link. A /nojs/ segment in its path is rewritten to /ajax/, so the server can tell a real Ajax request from a plain page load. For a submit button, use use-ajax-submit.

Cite this definition

"Ajax." DXPR Drupal glossary, https://dxpr.com/hc/documentation/learn-drupal/drupal-glossary/ajax. Last updated October 26, 2026.

Related terms

All Drupal terms from A to Z