twbs/bootstrap · error · TypeError

Bootstrap's dropdowns require Popper (https://popper.js.org/

Error message

Bootstrap's dropdowns require Popper (https://popper.js.org/docs/v2/)

What it means

Dropdown._createPopper() (dropdown.js:225) runs when a menu is first shown and throws when the Popper namespace is undefined. In the source, Popper is an ESM import from @popperjs/core, but the standalone UMD build (dist/js/bootstrap.js) keeps it external and expects a window.Popper global — so this error means the positioning library never became available. bootstrap.bundle.js and npm/ESM usage include Popper and do not hit this path.

Source

Thrown at js/src/dropdown.js:227

    EventHandler.trigger(this._element, EVENT_HIDDEN, relatedTarget)
  }

  _getConfig(config) {
    config = super._getConfig(config)

    if (typeof config.reference === 'object' && !isElement(config.reference) &&
      typeof config.reference.getBoundingClientRect !== 'function'
    ) {
      // Popper virtual elements require a getBoundingClientRect method
      throw new TypeError(`${NAME.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`)
    }

    return config
  }

  _createPopper() {
    if (typeof Popper === 'undefined') {
      throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org/docs/v2/)')
    }

    let referenceElement = this._element

    if (this._config.reference === 'parent') {
      referenceElement = this._parent
    } else if (isElement(this._config.reference)) {
      referenceElement = getElement(this._config.reference)
    } else if (typeof this._config.reference === 'object') {
      referenceElement = this._config.reference
    }

    const popperConfig = this._getPopperConfig()
    this._popper = Popper.createPopper(referenceElement, this._menu, popperConfig)
  }

  _isShown() {
    return this._menu.classList.contains(CLASS_NAME_SHOW)

View on GitHub (pinned to 6177d5f849)

Solutions

  1. Switch to the bundle build that already contains Popper: dist/js/bootstrap.bundle(.min).js.
  2. Or load Popper's UMD build before bootstrap.js: <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2/dist/umd/popper.min.js"></script>.
  3. With npm, import from 'bootstrap' so the bundler resolves @popperjs/core itself.
  4. Check the Network tab — the popper script must load successfully (no 404, not blocked).

Example fix

<!-- before: UMD build without Popper -->
<script src="bootstrap.min.js"></script>
<script>new bootstrap.Dropdown(document.querySelector('.dropdown-toggle'))</script>
<!-- TypeError: Bootstrap's dropdowns require Popper -->

<!-- after, option A: the bundle that contains Popper -->
<script src="bootstrap.bundle.min.js"></script>

<!-- after, option B: Popper first, then bootstrap -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2/dist/umd/popper.min.js"></script>
<script src="bootstrap.min.js"></script>
Defensive patterns

Strategy: validation

Validate before calling

function ensurePopper() {
  if (typeof window !== 'undefined' && typeof window.Popper === 'undefined') {
    throw new Error('Popper is missing — load bootstrap.bundle.js or @popperjs/core UMD before bootstrap.js')
  }
}
ensurePopper()
bootstrap.Dropdown.getOrCreateInstance(toggleEl).toggle()

Try / catch

try {
  bootstrap.Dropdown.getOrCreateInstance(toggleEl).toggle()
} catch (err) {
  if (err instanceof TypeError && /require Popper/.test(err.message)) {
    // positioning library missing: show a CSS-only fallback menu or load popper, then retry once
  } else {
    throw err
  }
}

Prevention

When it happens

Trigger: Loading dist/js/bootstrap.js without a <script> for @popperjs/core; the Popper CDN request 404-ing or being blocked by an ad blocker while bootstrap.js loads from cache; a bundler config that marks @popperjs/core external for UMD output without providing the global; jsdom test setups that never load the Popper script.

Common situations: CDN setups mixing slim and bundle builds; offline development; corporate proxies stripping CDN scripts; custom Rollup/webpack builds of the component source; upgrading a page that previously bundled everything.

Related errors


AI-assisted analysis of twbs/bootstrap@6177d5f849 (2026-08-22). Data as JSON: /api/errors/61586dfc94d4c6cb. Report an issue: GitHub.