{"record":{"id":"e54f130a3cc63846","repo":"Meituan-Dianping/mpvue","slug":"unknown-custom-element-tag-did-you-registe","errorCode":null,"errorMessage":"Unknown custom element: <${tag}> - did you register the component correctly? For recursive components, make sure to provide the \"name\" option.","messagePattern":"Unknown custom element: <(.+?)> - did you register the component correctly\\? For recursive components, make sure to provide the \"name\" option\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/core/vdom/patch.js","lineNumber":129,"sourceCode":"    if (createComponent(vnode, insertedVnodeQueue, parentElm, refElm)) {\n      return\n    }\n\n    const data = vnode.data\n    const children = vnode.children\n    const tag = vnode.tag\n    if (isDef(tag)) {\n      if (process.env.NODE_ENV !== 'production') {\n        if (data && data.pre) {\n          inPre++\n        }\n        if (\n          !inPre &&\n          !vnode.ns &&\n          !(config.ignoredElements.length && config.ignoredElements.indexOf(tag) > -1) &&\n          config.isUnknownElement(tag)\n        ) {\n          warn(\n            'Unknown custom element: <' + tag + '> - did you ' +\n            'register the component correctly? For recursive components, ' +\n            'make sure to provide the \"name\" option.',\n            vnode.context\n          )\n        }\n      }\n      vnode.elm = vnode.ns\n        ? nodeOps.createElementNS(vnode.ns, tag)\n        : nodeOps.createElement(tag, vnode)\n      setScope(vnode)\n\n      /* istanbul ignore if */\n      if (__WEEX__) {\n        // in Weex, the default insertion order is parent-first.\n        // List items can be optimized to use children-first insertion\n        // with append=\"tree\".\n        const appendAsTree = isDef(data) && isTrue(data.appendAsTree)","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/Meituan-Dianping/mpvue/blob/6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b/src/core/vdom/patch.js#L111-L147","documentation":"During patching, Vue encountered an element tag that is not a registered component, not a reserved HTML element, and not in `ignoredElements`, so `config.isUnknownElement(tag)` returns true. The element renders as a plain unknown custom element (behaves like a generic inline element with no component logic).","triggerScenarios":"Using `<my-widget>` in a template without `Vue.component('my-widget', ...)` or a local `components: { 'my-widget': ... }` registration; recursive component without a `name` option; unregistered kebab/case-mismatched component names; native Web Components not listed in `ignoredElements`.","commonSituations":"Case mismatch (`MyComponent` used as `<my-component>` without registration); forgetting `components: {}` local registration in SFC-less setups; upgrading from global registration to module-scoped components; using custom elements from other frameworks without configuring `Vue.config.ignoredElements`.","solutions":["Register the component globally (`Vue.component('my-widget', MyWidget)`) or locally in the parent's `components` option","Give recursive components a `name` option matching the tag","Match the tag casing exactly (kebab-case in DOM templates, PascalCase allowed in SFC templates)","If it's a native/Web Component, add it to `Vue.config.ignoredElements = [/^my-/]`"],"exampleFix":"// before\n<template><my-widget /></template>\n// after\nimport MyWidget from './MyWidget.vue'\nexport default {\n  components: { MyWidget },\n  template: '<my-widget />'\n}","handlingStrategy":"validation","validationCode":"function ensureRegistered (Vue, names) {\n  names.forEach(name => {\n    if (!Vue.options.components[name]) {\n      throw new Error('Component not registered: ' + name)\n    }\n  })\n}","typeGuard":"function isKnownTag (tag, components, reserved) {\n  return Object.prototype.hasOwnProperty.call(components, tag) || reserved.includes(tag)\n}","tryCatchPattern":null,"preventionTips":["Register components locally in the parent's components option","Give recursive components a name option","Match kebab-case vs PascalCase per template style","Add third-party/native custom elements to Vue.config.ignoredElements"],"tags":["component-registration","vdom","template"],"backgroundTag":"unknown-custom-element","analyzedSha":"6c5d78ee04f58c6d782c456dfcf0fe63c0b7f89b","analyzedAt":"2026-09-02T05:17:40.946Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T11:17:12.671Z"}