Richard C.
—Custom elements are part of the Web Components specification in modern HTML. They are lowercase HTML elements including a dash, such as <person-details>
. This element is custom JS and HTML you write, that behaves in the same way as standard HTML elements like <div>
and <span>
.
Since custom element names look similar to components you create in React, Vue.js, or other web frameworks, the frameworks might be confused when encountering them.
You might get an error message like the following:
Failed to resolve component: component-name If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
You might see this error when you are working with a Laravel project that is using Vue.js as its browser framework. Vue.js is the underlying cause of the error.
The Vue.js documentation says:
By default, Vue will attempt to resolve a non-native HTML tag as a registered Vue component before falling back to rendering it as a custom element. This will cause Vue to emit a
failed to resolve component
warning during development. To let Vue know that certain elements should be treated as custom elements and skip component resolution, we can specify thecompilerOptions.isCustomElement
option.
Custom elements are compatible with Vue, but you need to tell your project you’re using one.
The most common cause for the Unknown custom element
error is not a configuration problem, but rather that you misspelled the tag. For example, instead of <person-details>
, you may have written <persan-details>
. Check your spelling before trying the other solutions below.
Removing the error message will differ depending on whether you are using Vue 2 or Vue 3.
Vue 2 was deprecated in 2023, but you might need to maintain an old project that has not yet upgraded to Vue 3.
Vue 2 documentation says you need to use Vue.config.ignoredElements
in your code or custom elements will cause an error.
For example:
Vue.config.ignoredElements = ['person-details']; const app = new Vue({ el: '#app', data: { message: 'Hello Vue!'} });
For a full working example, try the following index.html
file:
<html lang="en"> <head> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <!-- Create a web component --> <script> class PersonDetails extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); this.shadowRoot.innerHTML = `<p>Person Record Component</p>`; } } customElements.define("person-details", PersonDetails); </script> <div id="app"> {{ message }} <person-details></person-details> </div> <script> Vue.config.ignoredElements = ["person-details"]; var app = new Vue({ el: "#app", data: { message: "Hello Vue!", }, }); </script> </body> </html>
In Vue 3, the method to remove the error message will differ depending on whether you are creating Vue components at runtime or using a build step.
If you are creating a Vue application at runtime without a build step, you will have code to initialize your app similar to the following:
const { createApp } = Vue; const app = createApp({ data() { return { message: 'Hello Vue!' } } });
Below this, add the following configuration line:
app.config.compilerOptions.isCustomElement = (tag) => ['person-details', 'another-element'].includes(tag);
If you refresh the page, you should no longer get an error message.
For a full working example, try the following index.html
file:
<html lang="en"> <head> <script src="https://cdn.jsdelivr.net/npm/vue"></script> </head> <body> <!-- Create a web component --> <script> class PersonDetails extends HTMLElement { constructor() { super(); this.attachShadow({ mode: "open" }); this.shadowRoot.innerHTML = `<p>Person Record Component</p>`; } } customElements.define("person-details", PersonDetails); </script> <div id="app"> {{ message }} <person-details></person-details> </div> <script> const { createApp } = Vue; const app = createApp({ data() { return { message: "Hello Vue!" }; }, }); app.config.compilerOptions.isCustomElement = (tag) => ["person-details", "another-element"].includes(tag); app.mount("#app"); </script> </body> </html>
If you are using a JavaScript bundler, like Parcel, webpack, Browserify, or Vite — or working with TypeScript using tsc or Babel — you need to configure custom elements in your build step. (You might get rid of the error using only the app.config.compilerOptions.isCustomElement
line from the previous section, so try that first, but otherwise use the code in this section.)
For Vite, in the vite.config.js
file, you can use the template’s compilerOptions
object to set a function defining what a custom element name is. For example:
import vue from '@vitejs/plugin-vue' export default { plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => ['person-details', 'another-element'].includes(tag) } } }) ] }
If you’re using webpack, add a rule like the following to webpack.config.js
:
rules: [ { test: /\.vue$/, use: 'vue-loader', options: { compilerOptions: { isCustomElement: tag => ['person-details', 'another-element'].includes(tag) } } } ]
If you’re using Parcel or the old Vue CLI, add the isCustomElement
line to your vue.config.js
file.
If you still have trouble with custom elements in Vue, read the full documentation:
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODESConsidered “not bad” by 4 million developers and more than 100,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.
Here’s a quick look at how Sentry handles your personal information (PII).
×We collect PII about people browsing our website, users of the Sentry service, prospective customers, and people who otherwise interact with us.
What if my PII is included in data sent to Sentry by a Sentry customer (e.g., someone using Sentry to monitor their app)? In this case you have to contact the Sentry customer (e.g., the maker of the app). We do not control the data that is sent to us through the Sentry service for the purposes of application monitoring.
Am I included?We may disclose your PII to the following type of recipients:
You may have the following rights related to your PII:
If you have any questions or concerns about your privacy at Sentry, please email us at compliance@sentry.io.
If you are a California resident, see our Supplemental notice.