{"record":{"id":"2613411ff3e1da76","repo":"twbs/bootstrap","slug":"bootstrap-s-tooltips-require-popper-https-poppe","errorCode":null,"errorMessage":"Bootstrap's tooltips require Popper (https://popper.js.org/docs/v2/)","messagePattern":"Bootstrap's tooltips require Popper \\(https://popper\\.js\\.org/docs/v2/\\)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"js/src/tooltip.js","lineNumber":108,"sourceCode":"  offset: '(array|string|function)',\n  placement: '(string|function)',\n  popperConfig: '(null|object|function)',\n  sanitize: 'boolean',\n  sanitizeFn: '(null|function)',\n  selector: '(string|boolean)',\n  template: 'string',\n  title: '(string|element|function)',\n  trigger: 'string'\n}\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n  constructor(element, config) {\n    if (typeof Popper === 'undefined') {\n      throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org/docs/v2/)')\n    }\n\n    super(element, config)\n\n    // Private\n    this._isEnabled = true\n    this._timeout = 0\n    this._isHovered = null\n    this._activeTrigger = {}\n    this._popper = null\n    this._templateFactory = null\n    this._newContent = null\n\n    // Protected\n    this.tip = null\n\n    this._setListeners()\n","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/twbs/bootstrap/blob/6177d5f8497f2c08f9874f5221fd17ce5acd2ad7/js/src/tooltip.js#L90-L126","documentation":"Tooltip's constructor checks the Popper namespace before calling super() and throws immediately — so new bootstrap.Tooltip(el) or Tooltip.getOrCreateInstance(el) itself fails, unlike Dropdown which only fails when the menu opens. It means @popperjs/core is absent at runtime: the standalone UMD build (dist/js/bootstrap.js) keeps Popper external and expects a window.Popper global, so a missing script, a CDN failure, or an externalized bundler config triggers it. Bundle builds (bootstrap.bundle.js) and npm/ESM usage include Popper and are immune.","triggerScenarios":"new bootstrap.Tooltip(el) or tooltip tooltip() init with dist/js/bootstrap.js loaded but no @popperjs/core script; a Popper CDN request blocked or 404-ing while bootstrap.js loads from cache; a custom Rollup/webpack build treating '@popperjs/core' as external for UMD output; jsdom tests that never load the Popper script.","commonSituations":"Pages initialized with $('...').tooltip() or data-bs-toggle=\"tooltip\" after a CDN change; ad blockers removing popper.js URLs; offline development; template layouts that conditionally load bootstrap but always load popper's slot empty.","solutions":["Switch to the bundle build that contains Popper: dist/js/bootstrap.bundle(.min).js.","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>.","With npm, import { Tooltip } from 'bootstrap' so the bundler resolves @popperjs/core.","Verify in the Network tab that the Popper script actually loads on the failing page."],"exampleFix":"<!-- before: UMD build, Popper never loaded -->\n<script src=\"bootstrap.min.js\"></script>\n<script>new bootstrap.Tooltip(document.querySelector('[data-bs-toggle=\"tooltip\"]'))</script>\n<!-- TypeError: Bootstrap's tooltips require Popper -->\n\n<!-- after, option A: bundle containing Popper -->\n<script src=\"bootstrap.bundle.min.js\"></script>\n\n<!-- after, option B: Popper before bootstrap -->\n<script src=\"https://cdn.jsdelivr.net/npm/@popperjs/core@2/dist/umd/popper.min.js\"></script>\n<script src=\"bootstrap.min.js\"></script>","handlingStrategy":"validation","validationCode":"function ensurePopper() {\n  if (typeof window !== 'undefined' && typeof window.Popper === 'undefined') {\n    throw new Error('Popper is missing — load bootstrap.bundle.js or @popperjs/core UMD before bootstrap.js')\n  }\n}\nensurePopper()\nbootstrap.Tooltip.getOrCreateInstance(el)","typeGuard":null,"tryCatchPattern":"try {\n  bootstrap.Tooltip.getOrCreateInstance(el)\n} catch (err) {\n  if (err instanceof TypeError && /require Popper/.test(err.message)) {\n    // skip tooltip init or dynamically load popper, then retry init once\n  } else {\n    throw err\n  }\n}","preventionTips":["Standardize script-tag builds on dist/js/bootstrap.bundle.min.js.","When using plain bootstrap.js, load the @popperjs/core UMD script before it.","In wrapper libraries, feature-detect window.Popper before initializing tooltips.","Check the Network tab for popper 404s or ad-blocker interference."],"tags":["bootstrap","tooltip","popper","missing-dependency","umd","cdn"],"backgroundTag":"missing-dependency","analyzedSha":"6177d5f8497f2c08f9874f5221fd17ce5acd2ad7","analyzedAt":"2026-08-22T03:20:03.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}