{"record":{"id":"43adabf96615daac","repo":"twbs/bootstrap","slug":"you-have-to-implement-the-static-method-name-fo","errorCode":null,"errorMessage":"You have to implement the static method \"NAME\", for each component!","messagePattern":"You have to implement the static method \"NAME\", for each component!","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/src/util/config.js","lineNumber":26,"sourceCode":"import Manipulator from '../dom/manipulator.js'\nimport { isElement, toType } from './index.js'\n\n/**\n * Class definition\n */\n\nclass Config {\n  // Getters\n  static get Default() {\n    return {}\n  }\n\n  static get DefaultType() {\n    return {}\n  }\n\n  static get NAME() {\n    throw new Error('You have to implement the static method \"NAME\", for each component!')\n  }\n\n  _getConfig(config) {\n    config = this._mergeConfigObj(config)\n    config = this._configAfterMerge(config)\n    this._typeCheckConfig(config)\n    return config\n  }\n\n  _configAfterMerge(config) {\n    return config\n  }\n\n  _mergeConfigObj(config, element) {\n    const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {} // try to parse\n\n    return {\n      ...this.constructor.Default,","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/twbs/bootstrap/blob/6177d5f8497f2c08f9874f5221fd17ce5acd2ad7/js/src/util/config.js#L8-L44","documentation":"Config is the abstract base that every component and several internal utilities (Backdrop, FocusTrap, Swipe, TemplateFactory) extend; its static NAME getter deliberately throws to force subclasses to define their own. NAME is load-bearing: BaseComponent builds the bs.* instance-storage key from it and Config's type-check error message prefixes it. The throw fires at construction time — instantiating a subclass that never overrode NAME.","triggerScenarios":"class MyWidget extends BaseComponent {} followed by new MyWidget(el) — no NAME override, so BaseComponent's data-key computation hits Config's throwing getter; the same for classes extending Config directly or utility classes like Backdrop without a NAME; third-party plugins built on bootstrap/src that skip the getter.","commonSituations":"Writing custom Bootstrap-style components by extending BaseComponent/Config; copying an old plugin template that predates the Config refactor; wrapping Bootstrap internals in a design system and forgetting one static getter.","solutions":["Add the override to the subclass: static get NAME() { return 'mywidget' }.","Copy the pattern from any built-in, e.g. js/src/alert.js:32 (static get NAME() { return 'alert' }).","Remember utilities need it too — Backdrop, FocusTrap, Swipe and TemplateFactory all declare NAME.","Return a short, unique, lowercase string; Bootstrap derives data keys and event names from it."],"exampleFix":"// before\nclass Widget extends BaseComponent {}\nnew Widget(el) // Error: You have to implement the static method \"NAME\", for each component!\n\n// after\nclass Widget extends BaseComponent {\n  static get NAME() { return 'widget' }\n}\nnew Widget(el)","handlingStrategy":"validation","validationCode":"// Property-descriptor check — does NOT invoke Config's throwing getter\nfunction declaresOwnName(Ctor) {\n  return Object.getOwnPropertyDescriptor(Ctor, 'NAME') !== undefined\n}\n\nif (!declaresOwnName(MyWidget)) {\n  throw new Error('MyWidget must define `static get NAME()` before instantiation')\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always add static get NAME() when extending BaseComponent or Config.","Copy the one-liner from any built-in (e.g. js/src/alert.js:32).","Remember internal utilities (Backdrop, FocusTrap, Swipe, TemplateFactory) need NAME too.","Add a construction-time unit test for custom components to catch the missing getter early."],"tags":["bootstrap","config","subclassing","custom-component","abstract-method"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"6177d5f8497f2c08f9874f5221fd17ce5acd2ad7","analyzedAt":"2026-08-22T03:20:03.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}