Skip to main content
The no-browser-dialogs rule prevents usage of the following native browser dialog APIs: alert(), confirm(), and prompt().

Rule details

UI extensions run in a sandboxed web worker environment where native browser dialog APIs (alert(), confirm(), and prompt()) are intentionally replaced with error-throwing functions for security reasons. These blocking dialogs would freeze the entire UI and negatively impact user experience. Instead, UI extensions provide non-blocking alternatives that integrate seamlessly with the HubSpot interface.

Dialog method alternatives

Use the following UI extension alternatives instead of browser dialog APIs:
Native APIAlternativePurpose
alert() (for pop-ups)actions.addAlert()Display toast notifications
alert() (for inline alerts)<Alert> componentDisplay inline alerts
confirm()<Modal> + <Button> componentsGet user confirmation
prompt()<Modal> + <Input> componentsGet user text input
See the next section for an example of each alternative.

Examples

Global alerts

Instead of using global alert():
// Incorrect
function showWarning() {
  alert('Please save your work!');
}
...
window.alert('Operation completed');
Use actions.addAlert() from the SDK:
import { Text } from '@hubspot/ui-extensions';

const Extension = ({ actions }) => {
  const showWarning = () => {
    actions.addAlert({
      type: 'warning',
      message: 'Please save your work!',
    });
  };

  return <Text>Content here</Text>;
};

export default hubspot.extend(({ actions }) => (
  <Extension actions={actions} />
));
Or use the <Alert> component for inline alerts:
import { Alert, Text } from '@hubspot/ui-extensions';

const Extension = () => {
  return (
    <>
      <Alert title="Warning" variant="warning">
        <Text>Please save your work!</Text>
      </Alert>
    </>
  );
};

Confirmations

Instead of using confirm() as shown below:
// Incorrect
function deleteItem() {
  if (confirm('Are you sure you want to delete this?')) {
    // Delete logic
  }
}

// Also incorrect
const result = globalThis.confirm('Continue?');
Use a combination of <Modal> and <Button> components:
// Correct

import {
  Button,
  Modal,
  ModalBody,
  ModalFooter,
  Text,
} from '@hubspot/ui-extensions';

const Extension = ({ actions }) => {
  const handleDelete = () => {
    // Perform delete operation
    actions.addAlert({
      type: 'success',
      message: 'Item deleted successfully',
    });
  };

  return (
    <Button
      variant="destructive"
      overlay={
        <Modal
          id="delete-confirmation"
          title="Confirm Deletion"
          width="small"
          variant="danger"
        >
          <ModalBody>
            <Text>Are you sure you want to delete this item?</Text>
          </ModalBody>
          <ModalFooter>
            <Button
              variant="destructive"
              onClick={(_, closeOverlay) => {
                handleDelete();
                closeOverlay();
              }}
            >
              Delete
            </Button>
            <Button
              variant="secondary"
              onClick={(_, closeOverlay) => closeOverlay()}
            >
              Cancel
            </Button>
          </ModalFooter>
        </Modal>
      }
    >
      Delete Item
    </Button>
  );
};

Prompts

Instead of using prompt():
// Incorrect
function getUserInput() {
  const name = prompt('Enter your name:');
  return name;
}

// Also incorrect
const value = self.prompt('Enter a value:', 'default');

Use a combination of <Modal> and <Input> components:
import {
  Button,
  Input,
  Modal,
  ModalBody,
  ModalFooter,
  Text,
} from '@hubspot/ui-extensions';
import { useState } from 'react';

const Extension = ({ actions }) => {
  const [inputValue, setInputValue] = useState('');

  const handleSubmit = () => {
    actions.addAlert({
      type: 'success',
      message: `You entered: ${inputValue}`,
    });
  };

  return (
    <Button
      overlay={
        <Modal id="user-input" title="Enter Your Name" width="small">
          <ModalBody>
            <Input
              name="userInput"
              label="Name"
              value={inputValue}
              onChange={(value) => setInputValue(value)}
            />
          </ModalBody>
          <ModalFooter>
            <Button
              variant="primary"
              onClick={(_, closeOverlay) => {
                handleSubmit();
                closeOverlay();
              }}
            >
              Submit
            </Button>
            <Button
              variant="secondary"
              onClick={(_, closeOverlay) => closeOverlay()}
            >
              Cancel
            </Button>
          </ModalFooter>
        </Modal>
      }
    >
      Get Input
    </Button>
  );
};
Last modified on February 19, 2026