DEV Community

Orbit Websites
Orbit Websites

Posted on

Mozilla Takes Aim at Chrome's Prompt API: A Battle for User Control

Mozilla Takes Aim at Chrome's Prompt API: A Battle for User Control

In recent years, browser vendors have been rethinking how websites interact with users—especially when it comes to permissions, popups, and data access. One key battleground? The prompt() API.

While Chrome and other Chromium-based browsers have long supported the classic window.prompt() for simple user input, Mozilla Firefox has taken a more privacy-conscious stance—limiting and discouraging its use in modern web development. This isn’t just about preference; it’s a philosophical shift toward user control and security.

In this tutorial, we’ll explore:

  • What the prompt() API does
  • Why Mozilla is pushing back
  • How to build modern, accessible alternatives
  • A step-by-step replacement using HTML, CSS, and JavaScript

Let’s dive in.


What Is window.prompt()?

The prompt() method is a built-in browser function that displays a modal dialog asking the user for input:

const name = prompt("What's your name?");
console.log(name); // Logs user input or null if canceled
Enter fullscreen mode Exit fullscreen mode

It’s simple, synchronous, and requires zero setup. But simplicity comes at a cost.


Why Mozilla Is Saying “No” to prompt()

Mozilla has been vocal about deprecating disruptive, non-standard UI patterns like alert(), confirm(), and prompt(). Here’s why:

  • Poor user experience – Blocks the entire page
  • Not customizable – Can’t style or enhance
  • Accessibility issues – Hard to navigate with screen readers
  • Security risks – Phishing-prone (fake prompts)
  • Not mobile-friendly – Awkward on touch devices

Instead, Mozilla encourages developers to build custom, accessible, and user-friendly modals.

🔥 Pro Tip: Modern browsers may block prompt() in cross-origin iframes or during automated flows.


Step-by-Step: Replace prompt() with a Custom Modal

Let’s build a clean, accessible alternative that works across all browsers—including Firefox.

Step 1: HTML Structure

Create a modal with an input field and buttons:

<!-- Custom Prompt Modal -->
<div id="custom-prompt" class="modal hidden">
  <div class="modal-content">
    <p id="prompt-message">Enter your name:</p>
    <input type="text" id="prompt-input" autofocus />
    <div class="modal-buttons">
      <button id="prompt-cancel">Cancel</button>
      <button id="prompt-submit">OK</button>
    </div>
  </div>
</div>

<!-- Trigger Button -->
<button id="open-prompt">Ask Name</button>
Enter fullscreen mode Exit fullscreen mode

Step 2: Add CSS Styling

Make it look clean and responsive:

.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal-content {
  background: white;
  padding: 20px;
  border-radius: 8px;
  width: 90%;
  max-width: 400px;
  text-align: center;
}

#prompt-input {
  width: 100%;
  padding: 10px;
  margin: 10px 0;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 16px;
}

.modal-buttons {
  margin-top: 15px;
}

.modal-buttons button {
  padding: 8px 16px;
  margin: 0 5px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

#prompt-cancel {
  background: #f44336;
  color: white;
}

#prompt-submit {
  background: #4CAF50;
  color: white;
}

.hidden {
  display: none;
}
Enter fullscreen mode Exit fullscreen mode

Step 3: JavaScript Logic

Now, replace prompt() with a promise-based custom function:


javascript
class CustomPrompt {
  constructor() {
    this.modal = document.getElementById('custom-prompt');
    this.messageEl = document.getElementById('prompt-message');
    this.inputEl = document.getElementById('prompt-input');
    this.cancelBtn = document.getElementById('prompt-cancel');
    this.submitBtn = document.getElementById('prompt-submit');

    this.resolvePromise = null;

    // Close on cancel
    this.cancelBtn.addEventListener('click', () => {
      this.close(null);
    });

    // Close on submit
    this.submitBtn.addEventListener('click', () => {
      this.close(this.inputEl.value.trim() || null);
    });

    // Close on ESC key
    document.addEventListener('keydown', (e) => {
      if (e.key === 'Escape') {
        this.close(null);
      }
    });

    // Close when clicking outside
    this.modal.addEventListener('click', (e) => {
      if (e.target === this.modal) {
        this.close(null);
      }
    });
  }

  // Show prompt and return a promise
  show(message = 'Enter value:', defaultValue = '') {
    this.messageEl.textContent = message;
    this.inputEl.value = defaultValue;

    this.modal.classList.remove('hidden');

    // Focus input after render
    setTimeout(() => this.inputEl.focus(), 100);

    // Return a promise that resolves when user submits

---

☕ **Appreciative**
Enter fullscreen mode Exit fullscreen mode

Top comments (0)