play() failed because the user didn't interact with the document first

avatar
Borislav Hadzhiev

Last updated: Mar 7, 2024
3 min

banner

# play() failed because the user didn't interact with the document first

To solve the "Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first" error, set the muted attribute on the video element to true. When autoplay is enabled, the video element has to be muted.

domexception play failed because the user didnt interact with the document first

shell
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

Here is an example of how to set the muted attribute on the video element to true to enable autoplay.

index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <video controls width="250" src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/webm" title="Example Video" autoplay="true" muted="true" ></video> <script src="index.js"></script> </body> </html>
The code for this article is available on GitHub

The autoplay attribute only works if the muted attribute is set to true.

As this section of the Chrome docs states:

  • Muted autoplay is always allowed.
  • Autoplay with sound is allowed if the user has interacted with the domain (click, tap, etc).

If you have a video element and a source element, make sure to set the muted attribute on the video element.

index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <video controls width="250" autoplay="true" muted="true"> <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/webm" /> </video> <script src="index.js"></script> </body> </html>
The code for this article is available on GitHub

If you get the error when using Angular, you can set the muted attribute to true programmatically.

index.ts
playVideo() { const media = this.videoplayer.nativeElement; media.muted = true; media.play(); }

setting muted attribute to true

The code for this article is available on GitHub

Here is an example that sets the muted attribute on a video element to true programmatically in JavaScript.

index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <video id="video" controls width="250"> <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/webm" /> </video> <script src="index.js"></script> </body> </html>

And here is the related JavaScript code.

index.js
const videoEl = document.getElementById('video'); videoEl.muted = true; videoEl.play();

You can also use a mouseover event, but once you set the video element to not be muted, the video stops playing and requires the user to click once to play with sound.

index.js
const videoEl = document.getElementById('video'); videoEl.muted = true; videoEl.play(); document.body.addEventListener('mouseover', () => { videoEl.muted = false; });

When you load the page:

  1. The video starts playing.
  2. When you hover over the video, it gets unmuted and stops playing.
  3. When you click on the video once, it starts playing with sound.

# Starting the video when the user clicks on a different element

Alternatively, you can start the video when the user clicks on a different element, e.g. a button.

index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <button id="btn">Play video with sound</button> <video id="video" controls width="350"> <source src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/webm" /> </video> <script src="index.js"></script> </body> </html>
The code for this article is available on GitHub

And here is the related JavaScript code.

index.js
const btn = document.getElementById('btn'); const videoEl = document.getElementById('video'); btn.addEventListener('click', event => { videoEl.play(); });
The code for this article is available on GitHub

When the user clicks on the button, the video plays with audio.

We didn't have to set the muted attribute to true because the user has interacted with the domain by clicking on the button.

You can also start the video player with a delay after the user clicks on the button.

index.js
const btn = document.getElementById('btn'); const videoEl = document.getElementById('video'); btn.addEventListener('click', event => { videoEl.play().then(() => videoEl.pause()); setTimeout(() => videoEl.play(), 2000); });

When the user clicks on the button, the video player starts and is then paused.

After a 2-second delay, the video starts playing with audio again.

You can also use a button to start playing an audio element with sound.

index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body style="margin-left: 500px; margin-top: 200px"> <button id="btn">Play audio with sound</button> <figure> <figcaption>Listen to the T-Rex:</figcaption> <audio id="audio" controls src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" ></audio> </figure> <script src="index.js"></script> </body> </html>
The code for this article is available on GitHub

And here is the related JavaScript code.

index.js
const audioEl = document.getElementById('audio'); btn.addEventListener('click', event => { audioEl.play(); });
The code for this article is available on GitHub

Once the user clicks on the button, the audio element starts playing with sound.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.