How to Pass Custom Headers in Howler.js

This article explains how to pass custom HTTP headers when loading audio files with the Howler.js library. While default HTML5 audio elements do not support custom headers, you can achieve this in Howler.js by utilizing the Web Audio API and configuring the built-in XMLHttpRequest (XHR) options, or by pre-fetching the audio using the Fetch API.

Method 1: Using the Native XHR Option (Web Audio API)

Howler.js allows you to pass custom headers directly through the xhr configuration property. This method requires Web Audio API to be enabled, meaning you must set html5: false (which is the default setting in Howler.js).

Here is how to configure custom headers using the xhr property:

const sound = new Howl({
  src: ['https://yourserver.com/audio.mp3'],
  html5: false, // Web Audio API must be enabled for XHR headers to work
  xhr: {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer your-access-token',
      'X-Custom-Header': 'custom-value'
    },
    withCredentials: true // Set to true if you need to send cookies/credentials
  }
});

sound.play();

Method 2: Fetching the Audio as a Blob (For HTML5 Audio streaming)

If you must use html5: true (which is highly recommended for large audio files to enable streaming and reduce memory usage), the native xhr property in Howler.js will not work because standard HTML5 <audio> tags do not support custom request headers.

To bypass this limitation, you can fetch the audio file manually using the browser’s fetch API, convert the response into an object URL, and pass that URL to Howler.js:

// 1. Fetch the audio file with custom headers
fetch('https://yourserver.com/audio.mp3', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer your-access-token',
    'X-Custom-Header': 'custom-value'
  }
})
.then(response => {
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.blob();
})
.then(blob => {
  // 2. Create a local object URL from the blob
  const blobUrl = URL.createObjectURL(blob);

  // 3. Pass the object URL to Howler
  const sound = new Howl({
    src: [blobUrl],
    format: ['mp3'], // You must explicitly define the format when using blob URLs
    html5: true
  });

  sound.play();
})
.catch(error => {
  console.error('Error loading audio:', error);
});

Key Considerations