JavaScript Document exitPictureInPicture() Method

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Limited availability
Instance method

What You’ll Learn

document.exitPictureInPicture() is an instance method that asks the browser to leave Picture-in-Picture mode (see MDN Document: exitPictureInPicture()). Learn its Promise return, the InvalidStateError when nothing is in PiP, how it pairs with HTMLVideoElement.requestPictureInPicture() and pictureInPictureElement, and five try-it labs.

01

Kind

Instance method

02

Params

None

03

Returns

Promise

04

Reverses

requestPictureInPicture

05

Guard

pictureInPictureElement

06

Status

Limited availability

Introduction

Picture-in-Picture (PiP) floats a video in a small window so users can keep watching while browsing other tabs or apps. You enter PiP with video.requestPictureInPicture(). To leave from script, call document.exitPictureInPicture().

MDN: this method requests that a video currently floating in PiP be taken out of that mode, restoring the previous screen state. It usually reverses a previous requestPictureInPicture() call.

💡
Think: exit door for the floating video

1) Check document.pictureInPictureElement
2) If set, call document.exitPictureInPicture()
3) Await the Promise (or use .then() / .catch())
4) Sync UI with leavepictureinpicture / property checks

Related tutorials: pictureInPictureElement, pictureInPictureEnabled, exitFullscreen().

Understanding document.exitPictureInPicture()

An instance method on the page’s document object (Picture-in-Picture API; MDN).

  • Parameters — none (MDN).
  • Return value — a Promise that resolves when exiting PiP finishes (MDN).
  • Errors — if exiting fails, the promise rejects; handle with catch() (MDN).
  • InvalidStateError — thrown when document.pictureInPictureElement is null (MDN).
  • Pair — enter with HTMLVideoElement.requestPictureInPicture(); exit with this method.
  • Tracking — listen for enterpictureinpicture / leavepictureinpicture on the video (MDN).

📝 Syntax

General form of Document.exitPictureInPicture (MDN):

JavaScript
exitPictureInPicture()

Parameters

None (MDN).

Return value

A Promise resolved once the user agent has finished exiting picture-in-picture mode. On failure, use the promise’s catch() handler (MDN).

Exceptions

  • InvalidStateError — thrown if document.pictureInPictureElement is null (MDN).

MDN toggle example

JavaScript
document.onclick = (event) => {
  if (document.pictureInPictureElement) {
    document
      .exitPictureInPicture()
      .then(() => console.log("Document Exited from Picture-in-Picture mode"))
      .catch((err) => console.error(err));
  } else {
    video.requestPictureInPicture();
  }
};

MDN: to track which video is in PiP, listen for enterpictureinpicture / leavepictureinpicture on the video, or compare document.pictureInPictureElement to your HTMLVideoElement.

⚡ Quick Reference

GoalCode
Exit PiPawait document.exitPictureInPicture()
Safe exitif (document.pictureInPictureElement) { await document.exitPictureInPicture(); }
Enter PiPawait video.requestPictureInPicture()
Capabilitydocument.pictureInPictureEnabled
Feature-detecttypeof document.exitPictureInPicture === "function"
MDN statusLimited availability (not Baseline)

🔍 At a Glance

Four facts about document.exitPictureInPicture().

Returns
Promise

async exit

Params
none

MDN

If null
InvalidStateError

guard first

Status
limited

Not Baseline

📋 Script exit vs browser PiP UI

exitPictureInPicture()Browser / OS PiP close
Who starts it?Your scriptThe user
Promise?Yes — resolve / reject (MDN)No script Promise
If nothing in PiPInvalidStateError (MDN)N/A
UI syncStill listen for leave eventsSame leave events fire

Examples Gallery

Examples follow MDN Document: exitPictureInPicture() and practical PiP patterns. Entering PiP needs a real video and often a user gesture; support varies by browser.

📚 Getting Started

Toggle PiP like MDN’s sample.

Example 1 — MDN: click to toggle PiP

If already in PiP, exit; otherwise request PiP on a video.

JavaScript
const video = document.querySelector("#player");

document.onclick = () => {
  if (document.pictureInPictureElement) {
    document
      .exitPictureInPicture()
      .then(() => console.log("Document Exited from Picture-in-Picture mode"))
      .catch((err) => console.error(err));
  } else {
    video.requestPictureInPicture();
  }
};
Try It Yourself

How It Works

MDN uses document.pictureInPictureElement as the branch: truthy means “something is in PiP,” so call exitPictureInPicture().

Example 2 — Guard + await

Only exit when active; avoid InvalidStateError.

JavaScript
async function leavePiP() {
  if (!document.pictureInPictureElement) {
    console.log("not in picture-in-picture");
    return;
  }
  await document.exitPictureInPicture();
  console.log("exited PiP");
}

document.getElementById("exit").addEventListener("click", () => {
  leavePiP().catch((err) => console.error(err));
});
Try It Yourself

How It Works

MDN: calling exit when pictureInPictureElement is null throws InvalidStateError. Guarding first is the beginner-safe pattern.

📈 Practical Patterns

Helpers, events, and feature detection.

Example 3 — Safe exit helper

Return early (or return the Promise) only when PiP is active.

JavaScript
function exitPictureInPictureSafe() {
  if (document.pictureInPictureElement) {
    return document.exitPictureInPicture();
  }
  return Promise.resolve("already windowed");
}

exitPictureInPictureSafe()
  .then((msg) => console.log(msg || "exit finished"))
  .catch((err) => console.error(err));
Try It Yourself

How It Works

Returning a resolved Promise keeps call sites able to always chain .then() / .catch() without special-casing.

Example 4 — Sync UI on leavepictureinpicture

Keep a label correct whether exit came from your button or the PiP window UI.

JavaScript
const video = document.querySelector("#player");
const status = document.getElementById("status");

function updateStatus() {
  status.textContent = document.pictureInPictureElement
    ? "PiP: " + document.pictureInPictureElement.id
    : "not in PiP";
}

video.addEventListener("enterpictureinpicture", updateStatus);
video.addEventListener("leavepictureinpicture", updateStatus);
updateStatus();

document.getElementById("exit").addEventListener("click", () => {
  if (document.pictureInPictureElement) {
    document.exitPictureInPicture().catch(console.error);
  }
});
Try It Yourself

How It Works

MDN recommends video-level enter/leave events (or comparing pictureInPictureElement) so UI stays honest after any exit path.

Example 5 — Feature-detect before use

MDN marks Limited availability — check before shipping PiP controls.

JavaScript
const canExit = typeof document.exitPictureInPicture === "function";
const canEnter =
  typeof HTMLVideoElement !== "undefined" &&
  typeof HTMLVideoElement.prototype.requestPictureInPicture === "function";
const enabled = document.pictureInPictureEnabled === true;

console.log({ canExit, canEnter, enabled });
Try It Yourself

How It Works

Hide PiP buttons when the API is missing or pictureInPictureEnabled is false.

🚀 Common Use Cases

  • Video players — Exit PiP button next to Enter PiP.
  • Toggle controls — One button that enters or exits based on pictureInPictureElement.
  • Route changes — Leave PiP before navigating away from a watch page.
  • Single-video policy — Exit current PiP before opening another video in PiP.
  • Analytics — Log when script-driven exit completes.
  • Not a fullscreen replacement — PiP and fullscreen are separate presentation modes.

🧠 How exitPictureInPicture() Works

1

A video is in PiP

document.pictureInPictureElement points at that element (or is null).

State
2

Script calls exitPictureInPicture()

No arguments. If the element is null, expect InvalidStateError (MDN).

Request
3

Promise settles

Resolves when exit finishes; rejects on error (MDN).

Async
4

Floating window closes

pictureInPictureElement becomes null; leave events update UI.

📝 Notes

  • MDN: Limited availability (not Baseline) — feature-detect in production.
  • MDN: no parameters; returns a Promise.
  • MDN: InvalidStateError if pictureInPictureElement is null.
  • Usually reverses HTMLVideoElement.requestPictureInPicture() (MDN).
  • Users can also close PiP with browser / OS UI — keep event listeners.
  • Related: pictureInPictureElement, pictureInPictureEnabled, exitFullscreen().

Browser Support

Document.exitPictureInPicture() is marked Limited availability on MDN (not Baseline). Feature-detect with pictureInPictureEnabled before production use. Logos use the shared browser-image-sprite.png sprite from this project.

Limited availability · Not Baseline

Document.exitPictureInPicture()

Leave Picture-in-Picture with a Promise — pair with requestPictureInPicture and pictureInPictureElement.

Limited Check compat
Google Chrome Supported · Desktop & Android
Supported
Mozilla Firefox Supported in modern versions
Supported
Apple Safari Limited / platform-dependent PiP
Partial
Microsoft Edge Chromium PiP support
Supported
Opera Follow Chromium behavior
Supported
Internet Explorer No Picture-in-Picture API
Not supported
Document.exitPictureInPicture() Limited availability

Bottom line: Guard with pictureInPictureElement before exit. Handle the Promise, listen for leave events, and feature-detect for Limited availability.

Conclusion

document.exitPictureInPicture() closes the floating PiP window from script: no parameters, a Promise, and an InvalidStateError if nothing is in PiP. Guard with pictureInPictureElement, catch rejections, and keep UI honest with leave events.

Continue with pictureInPictureElement, exitPointerLock(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Check document.pictureInPictureElement before exiting
  • Handle the Promise with await + try/catch or .catch()
  • Listen for leavepictureinpicture to update buttons and labels
  • Feature-detect and check pictureInPictureEnabled
  • Enter PiP from a user gesture via video.requestPictureInPicture()

❌ Don’t

  • Call exit when nothing is in PiP (triggers InvalidStateError)
  • Assume Baseline support in every browser yet (MDN: Limited availability)
  • Confuse PiP with fullscreen APIs
  • Forget users can close PiP with browser UI
  • Ignore promise rejections when exit fails

Key Takeaways

Knowledge Unlocked

Five things to remember about exitPictureInPicture()

Leave PiP with a Promise; guard when nothing is floating.

5
Core concepts
🔄02

Params

none

MDN
⚠️03

If null

InvalidStateError

MDN
04

Pair

requestPictureInPicture

video
🛡05

Status

Limited

not Baseline

❓ Frequently Asked Questions

MDN: Document.exitPictureInPicture() requests that a video in this document currently floating in picture-in-picture mode be taken out of PiP, restoring the previous screen state. It usually reverses HTMLVideoElement.requestPictureInPicture().
No. MDN does not mark Document.exitPictureInPicture() as Deprecated, Experimental, or Non-standard. It is Limited availability (not Baseline), so feature-detect in production.
A Promise that resolves when the user agent has finished exiting picture-in-picture mode. On failure, handle the rejection with catch() (MDN).
MDN: an InvalidStateError is thrown if document.pictureInPictureElement is null. Always check pictureInPictureElement before calling exitPictureInPicture().
Call video.requestPictureInPicture() on an HTMLVideoElement (usually from a user gesture). Check document.pictureInPictureEnabled first.
MDN: listen for enterpictureinpicture and leavepictureinpicture on the video element(s), or compare document.pictureInPictureElement to your video.
Did you know?

Like fullscreen, you enter on an element (HTMLVideoElement.requestPictureInPicture()) but exit on the Document. That is why status lives on document.pictureInPictureElement — one place to ask which video is floating.

Next: exitPointerLock()

Learn how to release pointer lock with document.exitPointerLock() and pointerlockchange events.

exitPointerLock() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful