How howler.js Handles CORS for Audio Files

This article explains how the howler.js library manages Cross-Origin Resource Sharing (CORS) when loading and playing audio files from external domains. You will learn about how howler.js behaves differently under its Web Audio API and HTML5 Audio modes, how to configure the library to handle CORS requests, and the server-side settings required to prevent playback failures.

Web Audio API vs. HTML5 Audio

Howler.js uses two different methods for playing audio, and each handles CORS differently: the Web Audio API (default) and HTML5 Audio (html5: true).

1. Web Audio API (Default)

By default, howler.js loads audio files using JavaScript’s XMLHttpRequest (XHR) to decode the audio data into an ArrayBuffer. Because XHR is used, browser security models strictly enforce CORS.

If the audio file is hosted on a different domain than the website running howler.js, the request will fail unless the hosting server explicitly permits cross-origin requests.

2. HTML5 Audio (html5: true)

When you set html5: true in your Howl configuration (typically used for large files or streaming), howler.js delivers audio using the standard HTML5 <audio> element.

To facilitate CORS for these elements, howler.js automatically sets the crossOrigin attribute of the created HTML5 Audio element to "anonymous". This tells the browser to request the audio file with CORS enabled, but without sending user credentials (like cookies or HTTP Basic authentication).

Configuring howler.js for CORS

Depending on your use case, you can configure how howler.js requests your audio files.

Using the xhr Configuration

If you are using the default Web Audio API and need to customize the request headers, credentials, or methods, howler.js provides an xhr option. This allows you to pass custom configurations directly to the underlying fetch or XHR request.

const sound = new Howl({
  src: ['https://external-domain.com/audio.mp3'],
  html5: false, // Uses Web Audio API
  xhr: {
    method: 'GET',
    headers: {
      'Authorization': 'Bearer token_here'
    },
    withCredentials: true
  }
});

Using HTML5 Audio

If you only need basic cross-origin streaming without complex credentials, force HTML5 Audio. Howler.js will handle the crossOrigin tagging automatically.

const stream = new Howl({
  src: ['https://streaming-server.com/live'],
  html5: true // Automatically sets crossOrigin = "anonymous"
});

Required Server-Side Configuration

Regardless of how howler.js is configured, the server hosting the audio files must be configured to allow cross-origin requests. If the server does not send the correct HTTP headers, the browser will block the audio.

To resolve CORS issues, ensure your file-hosting server (e.g., Apache, Nginx, AWS S3, or Cloudflare) includes the following headers in its response: