How to Detect Blocked Autoplay in Howler.js

Modern web browsers block audio from playing automatically to prevent intrusive noise, requiring a user gesture like a click or tap before audio can start. This article explains how to detect when a browser has blocked autoplay using the Howler.js library, allowing you to gracefully prompt users for interaction and ensure a seamless audio experience.

Understanding the Autoplay Restriction

Browsers restrict the Web Audio API by placing the audio context into a suspended state. Howler.js automatically attempts to unlock this audio context when a user interacts with the page (e.g., via a click or touch event). However, you still need to detect if autoplay was initially blocked so you can display an appropriate “Click to Play” UI to the user.

Detecting the Blocked State

To detect if autoplay has been blocked, you need to check the state of the global Web Audio context managed by Howler.js (Howler.ctx). If Howler.ctx exists and its state is 'suspended', the browser has blocked the audio from playing.

Here is the most direct way to check for a blocked autoplay state and handle the unlock event:

import { Howl, Howler } from 'howler';

// 1. Initialize and play your sound
const sound = new Howl({
  src: ['sound.mp3'],
  autoplay: true
});

// 2. Check if the browser blocked the audio context
if (Howler.ctx && Howler.ctx.state === 'suspended') {
  console.log("Autoplay was blocked by the browser.");
  
  // Show a UI overlay prompting the user to click/interact
  showPlaybackPrompt();

  // 3. Listen for Howler's global unlock event
  Howler.once('unlock', () => {
    console.log("Audio unlocked successfully!");
    hidePlaybackPrompt();
  });
} else {
  console.log("Audio is playing successfully.");
}

function showPlaybackPrompt() {
  // Logic to show a "Click to Play" button or overlay
}

function hidePlaybackPrompt() {
  // Logic to hide the button or overlay once audio is playing
}

How the Detection Code Works

  1. State Checking (Howler.ctx.state): The Howler.ctx property holds the underlying Web Audio API context. If the browser blocks autoplay, the state property of this context is set to 'suspended'.
  2. The unlock Event: Howler.js has a built-in global event emitter. By listening to Howler.once('unlock', callback), your application is notified the exact moment the user interacts with the page and Howler successfully resumes the audio context.

By checking the suspended state immediately after attempting playback, you can instantly decide whether to show a play button or let the audio run silently in the background.