Issues and feedback about Sounds in AI Chatbot

Howdy,

Following my last comment, I just noticed that the AI chatbot sounds do not work with iPhones and iPads (I have not checked other types of mobile devices and tablets).

Can you guys look into this? If the sounds work at your end, please let me know how to troubleshoot and fix them.

Thank you!

Update: The sounds work randomly on mobile devices and tablets. Also, the sounds play after a long delay (say, seconds or even minutes after the chatbox has been opened and closed). Not good. Tried everything.

Howdy,

In addition to what I provided above, please incorporate a feature into your configurator that will allow us to mute sounds in any combination for desktops, tablets, and mobile devices.

Thank you!

Hi there, @Adore :waving_hand:

Thank you so much for your feedback!

You’ve brought up some really interesting points, and I’ve discussed them with our devs. Here’s what they shared:


We chose sounds that are quite universal, so each of them can work well for any of the 3 available actions.


Since the sounds are pretty versatile, any of them can fit different use cases. That said, here are a couple of combinations our devs personally recommend:

a) Open Window - No Sound, Messages - Bubble
b) Open Window - Soft 2, Messages - Click


We’d also like to mention that having no sound can be a perfectly good choice too. You don’t necessarily need to set a sound for every action.


For messages, we’d especially recommend Bubble, Click, and Soft. They’re short, gentle, and easy to recognize.


Just to make sure I understood this part correctly, do you mean cases where the Greeting appears above the chat bubble after a delay?

Hi there, @Petar_Dietrich :waving_hand:

Many thanks for sharing your thoughts with us!

I’ve just tested this functionality several times on my iPhone and couldn’t replicate this issue. If it still persists, please specify:

  • the exact model of your devices (iPhone and iPad)

  • iOS version for both devices


A video screencast featuring the issue would also be much appreciated :folded_hands:

As for the device-specific options for the sound activation, this is a nice idea and I’ve added it to the Wishlist on your behalf - Option to activate Sounds individually for desktop, tablets and mobile

Hey @Max ,

@Petar_Dietrich 's statement is true, I tested this early on when the feature come out and thought it was a issue with my device now hearing it from his side I can display my findings:

  1. The delay on mobile appears to be a buffer potentially it has to grab the sound file to play it? we know the buffer is true at least because i noticed the Send Message Arrow took time to load a second later then usual.

  2. After Opening Window, Using A Message, & Agent Message is delivered will then the browser recognize all the sound files and play consistently without a buffer.

Question:

Is the agent message sound supposed to trigger when the message is starting, midway, or at the done? I’ve gotten mixed triggers, potentially due to some JS intervening.

Hey @Petar_Dietrich ,

I like these sounds you have chosen, I personally would go with User Message having the “Click” personally I like the be consistent if messages are going to have audio all of them should have it.

That’s why I’d like it for Welcome Message / Greeting to have it when it pops up after delay

@Max so yes this is true after pop up delay.

should I send over another AI Chatbot’s example of sounds for welcome message popup? I think it might help also solve the issue for the sound file buffer on mobile.

After additional testing, this does not appear to primarily be a permissions issue.

The behavior is more consistent with mobile browser audio initialization and asset loading, specifically on iOS Safari. On PC Chrome the issue does not appear present, which points more toward platform/browser handling differences rather than the chatbot feature itself failing.

Observed behavior:

  • First sound playback on mobile has a noticeable delay/buffer

  • After interaction and message activity, sounds begin playing consistently

  • The entire chatbot window appears to initialize more slowly during the first audio trigger

  • Once assets appear cached/initialized, the issue becomes much less noticeable

Most likely technical causes:

  1. Audio assets are not preloaded on mobile
    If the sound file is fetched only when first triggered, iOS Safari can introduce a delay before playback begins.

  2. iOS Safari audio context initialization
    Safari on iOS is known for stricter media handling. Audio systems often remain suspended until a user interaction initializes them. The first interaction may effectively be “unlocking” the audio pipeline.

  3. Mobile caching behavior differs from desktop
    Chrome on PC is generally more aggressive with preloading and caching assets, which could explain why the issue is difficult or impossible to reproduce there.

Most likely areas worth investigating:

  • preload sound assets during chatbot initialization

  • initialize/unlock audio context immediately after first user interaction

  • cache sounds in memory instead of loading on-demand

  • specifically test iOS Safari behavior against desktop browsers

At this point the evidence points more toward iOS Safari/mobile browser audio handling combined with initialization timing, rather than a permissions configuration problem.

Hey @Max,

@Adore is spot on! I can assure you, there’s an issue with sounds on iPhones and iPads.

We’re using iPhone 14 Pro Max phones, iPhone 16 Pro Max phones, and iPad Pro tablets. All devices loaded with the latest Apple software update: iOS 26.5 (effective May 11, 2026). What iPhone models and software are you using?

Also, can you tell us on what devices and operating systems your new sound feature was tested? Is there any way to disable the sound on mobile devices and tablets via JS/CSS?

So you know, we tested the sound features with the above devices under many Safari configurations (i.e., settings) and, of course, cleared cache prior to testing. Also, the tests were conducted using Wi-Fi (optimum case), but are still experiencing the issue.

Final action taken (for now): We disabled the new Sounds feature. This will ensure a consistent and equally-predictable chatbot behavior across all platforms, devices, and operating systems.

Thank you!

Actually, I’d like to add something else:

On PC there can still be interference if you click a Quick Reply/Suggested Message immediately after opening the chatbot window. This may be related to the same initial caching/loading behavior when the audio files are accessed for the first time.

If you wait a couple of seconds for the Opening Window sound to finish, then click a Quick Reply/Suggested Message, the audio usually plays correctly.

This seems similar to what is happening on mobile devices, except mobile behavior is noticeably worse and can remain buggy even in Incognito Mode or out of it.

Another possible cause could be how the browser is handling the sound library itself. Many AI chatbots only use one default audio file, but this chatbot allows users to choose from many different sounds. Because of that, the browser may be treating the audio assets as dynamic/changing files instead of static cached assets, which could cause additional loading or validation behavior on first playback.

Okay final idea, I’ll add on below :sweat_smile: :

Another possible factor could be the way the sound system is designed to support multiple states and user-selectable options.

Since the chatbot allows users to switch between many different sounds — including a “No Sound” option — the browser may be handling the audio assets more dynamically instead of treating them as permanently cached/static files. Depending on how the system initializes audio, the browser could be rechecking, loading, or validating sound assets during first use rather than keeping them persistently ready in memory.

That could help explain why the first playback after opening the chatbot is the most delayed, while later interactions become much smoother once the audio assets appear initialized or cached for the session.

Hey @Adore,

Thanks for your input. Much appreciated. We seem to be riding the same wave. For now, I disabled this feature for our website.

Cheers!

Folks, thank you so much for sharing your findings!

Please let me consult with the devs. I’ll keep you updated :slightly_smiling_face:

Hey @Max,

I did some research and found that the following may help fix the “buggy” behavior of the Sounds feature on mobile devices and tablets. Please forward this to your developers.

  1. Ensure all sound files are low-bitrate MP3 (around 20kb to 50kb) and are also using M4A Compressing the sound files and providing browser sound file type options is imperative.

  2. Ensure selected sound files are pre-loaded. If pre-loaded, are the chatbot sounds pre-loaded as Base64 strings or external files? Base64 strings play much faster on mobile devices because they don’t require a separate download.

  3. Are the sound files embedded into each widget’s code or are they hosted as a separate file? Embedding the sound files into each widget’s code will help minimize the issue.

  4. Use HTML code that is compatible across multiple browser and operating systems.

  5. Could Elfsight’s current widget installation code be part of the problem? It uses Async and Lazyload (Note: I did some testing at my end and it did not help).

  6. Consider developing a JS script that we can add to the chatbot configurator that will help improve the reported condition.

I hope this leads to a fix (or improvement) for the reported sound behavior on mobile devices and tablets.

Cheers!

Hey @Petar_Dietrich, @Adore :waving_hand:

Thanks for your patience!

@Petar_Dietrich The suggestions you shared are already implemented. The issue seems to be caused by Safari’s strict restrictions. Our developers need a bit more time to investigate, and I’ll update you here as soon as I have news.

Regarding your other questions:


@Petar_Dietrich

  • How to disable sounds on desktop/tablet/mobile only?

This CSS code hides the Mute button in the chat header individually for each device:

/* Desktop */
@media (min-width: 1024px) {
  .es-header-button-sound-mute {
    display: none;
  }
}

/* Tablet */
@media (min-width: 480px) and (max-width: 1024px) {
  .es-header-button-sound-mute {
    display: none;
  }
}

/* Mobile */
@media (max-width: 480px) {
  .es-header-button-sound-mute {
    display: none;
  }
}

And use this script in the Custom JS section of your widget’s Settings tab:

const WIDGET_ID = 'YOUR_WIDGET_ID';

const ALLOWED_DEVICES = {
	desktop: true, // false
	tablet: true, // false
	mobile: true, // false
};

const DESKTOP_BREAKPOINT = 1024; // px
const MOBILE_BREAKPOINT = 480; // px

const STORAGE_KEY = `AiChatbot.sound-notifications-muted.${WIDGET_ID}`;

const device =
	window.innerWidth >= DESKTOP_BREAKPOINT
		? 'desktop'
		: window.innerWidth > MOBILE_BREAKPOINT
			? 'tablet'
			: 'mobile';

if (!ALLOWED_DEVICES[device]) {
	const item = {
		timestamp: Date.now(),
		value: true,
	};

	localStorage.setItem(STORAGE_KEY, JSON.stringify(item));
}

  1. Replace YOUR_WIDGET_ID with your widget ID.
  2. Set true or false for each device in lines 4–6. For example:
  • desktop: true → sounds work on desktop
  • mobile: false → sounds disabled on mobile



@Adore, as for your questions:

  1. The sound plays only when the full agent message is sent.
  1. To add sounds to the Greeting Message, please add the code below to the Custom JS field on the Settings tab:
/*
Sound Variations:

bell
bell-2
bright
bright-2
bubble
bubble-2
click
click-2
digital
fantasy
glass
liquid
notes
plucky
soft
soft-2
*/

const SOUND_NAME = 'bell';
const VOLUME = 0.25; // [0; 1]

const audio = new Audio(
	`https://static.elfsight.com/configurator/assets/sounds/${SOUND_NAME}.mp3`
);
audio.volume = VOLUME;

const waitForElement = (selector, interval = 250) => {
	return new Promise((resolve) => {
		const timer = setInterval(() => {
			const element = util.findElement(selector);
			if (element) {
				clearInterval(timer);
				resolve(element);
			}
		}, interval);
	});
};

waitForElement('[class*="widget-welcome-window__Content-sc"]').then(() =>
	audio.play()
);

  • Replace bell with any sound from the list above
  • Adjust VOLUME to your preference

Thanks, @Max! Much appreciated. I will give the codes a spin and report back if any issues. Also, it would be great if your developers can eventually integrate into the AI chatbot configurator the codes you provided in the form of toggle switches. Cheers!

Yes, I totally get you. We’ll try to think about it in the future, especially if more users support this idea :slightly_smiling_face:

Hey @Max,

I tested both the CSS rules and JS code you provided above. They did not work for tablets and mobile phones. Also, the JS code you provided is invalid (per the AI Chatbot’s configurator).

Below is what worked for me. Also, please note that sounds will not play initially when using Firefox (natural behavior), only after user interaction with the chatbot.

Can you please ask your developers to triple-check? Note: Device emulators should not be used for testing, only real devices.

Thank you!


CSS Rules: (modified, works)

/* Hide Chat Header Mute Button */

/* Desktop */
@media (min-width: 1024px) {
  .es-header-button-sound-mute {
    display: none!important;
  }
}

/* Tablet Devices (Standard tablets AND desktop-mimicking iPads) */
@media (min-width: 768px) and (max-width: 1023px),
(min-width: 1024px) and (pointer: coarse) {
  .es-header-button-sound-mute {
    display: none !important;
  }
}

/* Mobile Devices (Everything under tablet width) */
@media (max-width: 767px) {
  .es-header-button-sound-mute {
    display: none !important;
  }
}

JS Code: (modified, works)


/* ---------------------------------------------------------
   DEVICE-BASED SOUND BLOCKER (with iPad/iOS WebAudio fix)
--------------------------------------------------------- */

const WIDGET_ID = 'YOUR_WIDGET_ID';

const ALLOWED_DEVICES = {
  desktop: true, // set to 'false' to disable sounds
  tablet: true, // set to 'true' to disable sounds
  mobile: true, // set to 'false' to disable sounds
};

const DESKTOP_BREAKPOINT = 1024;
const TABLET_BREAKPOINT = 768;

const STORAGE_KEY = `AiChatbot.sound-notifications-muted.${WIDGET_ID}`;

/* ---------------------------------------------------------
   RELIABLE iPAD DETECTION
--------------------------------------------------------- */

const isIpad =
  navigator.userAgent.includes("iPad") ||
  (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1);

/* ---------------------------------------------------------
   DEVICE DETECTION (width + iPad override)
--------------------------------------------------------- */

let deviceType = "mobile";

if (isIpad) {
  deviceType = "tablet";
} else if (window.innerWidth >= DESKTOP_BREAKPOINT) {
  deviceType = "desktop";
} else if (window.innerWidth >= TABLET_BREAKPOINT) {
  deviceType = "tablet";
}

/* ---------------------------------------------------------
   ONLY RUN BLOCKER IF DEVICE IS NOT ALLOWED
--------------------------------------------------------- */

if (!ALLOWED_DEVICES[deviceType]) {

  /* ---------------------------------------------------------
     MUTE STATE
  --------------------------------------------------------- */

  const applyMutePreference = () => {
    try {
      localStorage.setItem(
        STORAGE_KEY,
        JSON.stringify({ timestamp: Date.now(), value: true })
      );
    } catch (e) {}
  };

  /* ---------------------------------------------------------
     DOM AUDIO BLOCKER
  --------------------------------------------------------- */

  const muteAllAudioElements = () => {
    try {
      document.querySelectorAll("audio, video").forEach((el) => {
        el.muted = true;
        el.volume = 0;
        try { el.pause(); } catch (e) {}
      });
    } catch (e) {}
  };

  /* ---------------------------------------------------------
     HARD OVERRIDES — HTMLMediaElement
  --------------------------------------------------------- */

  (function () {
    HTMLMediaElement.prototype.play = function () {
      this.muted = true;
      this.volume = 0;
      try { this.pause(); } catch (e) {}
      return Promise.resolve();
    };
  })();

  /* ---------------------------------------------------------
     HARD OVERRIDE — new Audio()
  --------------------------------------------------------- */

  (function () {
    const OriginalAudio = window.Audio;

    window.Audio = function (...args) {
      const audio = new OriginalAudio(...args);
      audio.muted = true;
      audio.volume = 0;
      try { audio.pause(); } catch (e) {}
      return audio;
    };
  })();

  /* ---------------------------------------------------------
     HARD OVERRIDE — WebAudio API (iPad/iOS critical fix)
  --------------------------------------------------------- */

  (function () {
    const OriginalAudioContext =
      window.AudioContext || window.webkitAudioContext;

    if (!OriginalAudioContext) return;

    const FakeContext = function () {
      const ctx = new OriginalAudioContext();
      try { ctx.suspend(); } catch (e) {}
      return ctx;
    };

    window.AudioContext = FakeContext;
    window.webkitAudioContext = FakeContext;
  })();

  /* ---------------------------------------------------------
     INITIAL EXECUTION
  --------------------------------------------------------- */

  applyMutePreference();
  muteAllAudioElements();

  /* Staggered retries for lazy-loaded widgets */
  [250, 1000, 2500, 5000].forEach((t) => {
    setTimeout(applyMutePreference, t);
    setTimeout(muteAllAudioElements, t);
  });

  /* ---------------------------------------------------------
     VISIBILITY CHANGE (iOS tab resume fix)
  --------------------------------------------------------- */

  document.addEventListener("visibilitychange", () => {
    if (document.visibilityState === "visible") {
      applyMutePreference();
      muteAllAudioElements();
    }
  });

  /* ---------------------------------------------------------
     MUTATION OBSERVER — catch dynamically added audio
--------------------------------------------------------- */

  new MutationObserver(() => muteAllAudioElements()).observe(
    document.documentElement,
    { childList: true, subtree: true }
  );

  /* ---------------------------------------------------------
     SAFARI GESTURE NORMALIZATION
  --------------------------------------------------------- */

  document.addEventListener("touchstart", () => {}, { passive: true });
}

Hi there, @Petar_Dietrich :waving_hand:

Apologies for the inconvenience! Our devs just reviewed your new script and confirmed that it’s correct.

Regarding the CSS codes we’ve shared initally, I’ve just tested them and they’re working fine on my end. Could you please double-check it?

You’ve also mentioned that sounds play only after user interaction on Firefox, but all 3 sounds require interaction to be triggered:

  • Open Window - requires a click on the chat bubble

  • User Message - user must send a message using the widget

  • Agent Message - response given to a user message


Could you please elaborate on what you mean?

Hi @Max,

  1. Glad your developers confirmed my JS code works. Perhaps the original one needs to be updated?

  2. The CSS code you initially provided did not work for our iPhones and iPads (given the uniqueness of these devices). Mainly, iPads usually behave like Desktops so I had to adjust the code. Using your original CSS rules, the sound icon was still appearing on iPads (i..e, tablets), so I adjusted it.

  3. From my end, using Firefox (latest revision, no alterations), the Open Window sound does not work. Only the Agent Message and User Message sounds work after the chatbot processes information.

Thank you.

Got you!

I see that you’ve disabled sounds on tablet and mobile, so I’ve tested the Firefox issue on my laptop and the Open window sound is working fine there:


Do I get it right that you were referring to the issue on desktop? Or did you mean tablet and mobile?

If the issue occurs on desktop, please send me a video screencast of the issue and specify the exact device model.

Hey @Max,

So, the issue has been fixed. It was caused by:

  1. Dell Core Services app (installed via Dell Display and Peripheral Manager app). It was creating other issues on our Dell laptops/desktops, so I deleted the apps.

  2. My JS code above introduced a custom function (noted below) that broke Firefox’s sound behavior.

HTMLMediaElement.prototype.play = function () {
  this.muted = true;
  this.volume = 0;
  try { this.pause(); } catch (e) {}
  return Promise.resolve();
};

In Firefox, HTMLMediaElement.prototype.play() is expected to return the browser’s native Promise from the original implementation. My custom function broke it.

So, to fix the above and still retain the requirements for iOS devices, I updated the JS code. Use code below. If you agree, you’re welcome to “sanitize” this post by deleting all information that may confuse other readers/users. I’m OK with that.

I hope this helps. Thank you so much for your assistance and keeping me honest :slight_smile:

Cheers!


/* ---------------------------------------------------------
   DEVICE-BASED SOUND BLOCKER
   Firefox-safe + iOS/iPad-safe version
--------------------------------------------------------- */

const WIDGET_ID = 'YOUR_WIDGET_ID';

const ALLOWED_DEVICES = {
  desktop: true, // true = allow sounds
  tablet: true,  // true = allow sounds
  mobile: true,  // true = allow sounds
};

const DESKTOP_BREAKPOINT = 1024;
const TABLET_BREAKPOINT = 768;

const STORAGE_KEY = `AiChatbot.sound-notifications-muted.${WIDGET_ID}`;

/* ---------------------------------------------------------
   RELIABLE iPAD DETECTION
--------------------------------------------------------- */

const isIpad =
  navigator.userAgent.includes("iPad") ||
  (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1);

/* ---------------------------------------------------------
   DEVICE DETECTION (width + iPad override)
--------------------------------------------------------- */

let deviceType = "mobile";

if (isIpad) {
  deviceType = "tablet";
} else if (window.innerWidth >= DESKTOP_BREAKPOINT) {
  deviceType = "desktop";
} else if (window.innerWidth >= TABLET_BREAKPOINT) {
  deviceType = "tablet";
}

/* ---------------------------------------------------------
   ONLY RUN BLOCKER IF DEVICE IS NOT ALLOWED
--------------------------------------------------------- */

if (!ALLOWED_DEVICES[deviceType]) {

  /* ---------------------------------------------------------
     MUTE STATE
  --------------------------------------------------------- */

  const applyMutePreference = () => {
    try {
      localStorage.setItem(
        STORAGE_KEY,
        JSON.stringify({
          timestamp: Date.now(),
          value: true
        })
      );
    } catch (e) {}
  };

  /* ---------------------------------------------------------
     DOM AUDIO BLOCKER
  --------------------------------------------------------- */

  const muteAllAudioElements = () => {
    try {
      document.querySelectorAll("audio, video").forEach((el) => {

        try {
          el.muted = true;
          el.volume = 0;

          // Helps prevent autoplay continuation
          if (!el.paused) {
            el.pause();
          }
        } catch (e) {}

      });
    } catch (e) {}
  };

  /* ---------------------------------------------------------
     SAFE OVERRIDE — new Audio()
     Firefox/iOS compatible
  --------------------------------------------------------- */

  (function () {

    const OriginalAudio = window.Audio;

    if (!OriginalAudio) return;

    function SilentAudio(...args) {

      const audio = new OriginalAudio(...args);

      try {
        audio.muted = true;
        audio.volume = 0;
        audio.pause();
      } catch (e) {}

      return audio;
    }

    // Preserve prototype chain (important for Firefox)
    SilentAudio.prototype = OriginalAudio.prototype;

    window.Audio = SilentAudio;

  })();

  /* ---------------------------------------------------------
     SAFE OVERRIDE — WebAudio API
     iOS/iPad + Firefox compatible
  --------------------------------------------------------- */

  (function () {

    const OriginalAudioContext =
      window.AudioContext || window.webkitAudioContext;

    if (!OriginalAudioContext) return;

    function SilentAudioContext(...args) {

      const ctx = new OriginalAudioContext(...args);

      try {

        // Immediately suspend
        ctx.suspend();

        // Block future resume attempts
        const originalResume = ctx.resume?.bind(ctx);

        if (originalResume) {
          ctx.resume = () => Promise.resolve();
        }

      } catch (e) {}

      return ctx;
    }

    window.AudioContext = SilentAudioContext;
    window.webkitAudioContext = SilentAudioContext;

  })();

  /* ---------------------------------------------------------
     INITIAL EXECUTION
  --------------------------------------------------------- */

  applyMutePreference();
  muteAllAudioElements();

  /* ---------------------------------------------------------
     STAGGERED RETRIES
     Helps with lazy-loaded widgets/apps
  --------------------------------------------------------- */

  [250, 1000, 2500, 5000].forEach((t) => {

    setTimeout(() => {
      applyMutePreference();
      muteAllAudioElements();
    }, t);

  });

  /* ---------------------------------------------------------
     VISIBILITY CHANGE
     iOS/Safari tab restore fix
  --------------------------------------------------------- */

  document.addEventListener("visibilitychange", () => {

    if (document.visibilityState === "visible") {

      applyMutePreference();
      muteAllAudioElements();

    }

  });

  /* ---------------------------------------------------------
     PAGE FOCUS RESTORE
     Extra Firefox/iOS reliability
  --------------------------------------------------------- */

  window.addEventListener("focus", () => {

    applyMutePreference();
    muteAllAudioElements();

  });

  /* ---------------------------------------------------------
     MUTATION OBSERVER
     Catch dynamically inserted audio/video
  --------------------------------------------------------- */

  const observer = new MutationObserver(() => {
    muteAllAudioElements();
  });

  observer.observe(document.documentElement, {
    childList: true,
    subtree: true
  });

  /* ---------------------------------------------------------
     SAFARI/iOS GESTURE NORMALIZATION
  --------------------------------------------------------- */

  document.addEventListener(
    "touchstart",
    () => {},
    { passive: true }
  );

}