Replacing Drupal’s AJAX Throbber: A Step-by-Step Guide

Drupal provides a built-in throbber to indicate that an AJAX request is in progress. While the throbber is functional, it may not be visually appealing or match the design of your site. In this tutorial, we’ll walk through how to replace the Drupal AJAX throbber with a custom throbber that matches the design of your site.

We’ll be using vanilla JavaScript and CSS for this tutorial. In addition, we’ll be utilizing the following Bootstrap 5 classes; position-fixed top-0 start-0 end-0 bottom-0 bg-opacity-25 bg-dark w-100 h-100 to achieve the fixed overlay, if your theme doesn’t use bootstrap 5, you will need to convert those classes to pure CSS.

First, let’s take a look at the JavaScript code that creates the custom throbber:

((Drupal) => {
   * An animated progress throbber and container element for AJAX operations.
   * @param {string} 
* (optional) The message shown on the UI. * @return {string} * The HTML markup for the throbber. */ Drupal.theme.ajaxProgressThrobber = (message) => { // Build markup without adding extra white space since it affects rendering. const messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : ''; const throbber = '<svg class="custom-throbber" viewBox="0 0 60 60">\n' + '<circle class="path" cx="30" cy="30" r="25" fill="none" stroke-width="6"></circle>\n' + '</svg>'; return `<div class="custom-throbber-fullscreen position-fixed top-0 start-0 end-0 bottom-0 bg-opacity-25 bg-dark w-100 h-100">${throbber}${messageMarkup}</div>`; }; })(Drupal);

The code above defines a new Drupal theme function called ajaxProgressThrobber, which returns the HTML markup for the custom throbber. The markup includes an SVG element with a circle that animates using CSS.

Next, add the following CSS code to your website’s CSS file or style tag:

.custom-throbber-fullscreen {
  z-index: 1000;

.custom-throbber {
  animation: rotate 2s linear infinite;
  z-index: 2;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -25px 0 0 -25px;
  width: 50px;
  height: 50px;
  padding: 0.35rem;
  background: $white;
  border-radius: 50%;

  & .path {
    stroke: $primary;
    stroke-linecap: round;
    animation: dash 1.5s ease-in-out infinite;

@keyframes rotate {
  100% {
    transform: rotate(360deg);

@keyframes dash {
  0% {
    stroke-dasharray: 1, 150;
    stroke-dashoffset: 0;
    stroke: lighten($primary, 10%);
  50% {
    stroke-dasharray: 90, 150;
    stroke-dashoffset: -35;
  100% {
    stroke-dasharray: 90, 150;
    stroke-dashoffset: -124;
    stroke: darken($primary, 10%);

The code above styles the custom throbber. It sets the z-index property to ensure that the throbber appears above all other elements on the page.

With these steps, you can replace the default Drupal AJAX throbber with a custom SVG animation that matches the style of your website.

Credit the original author of the SVG animation code, which can be found on this CodePen: