Skip to content

Standard web components written in vanilla JS don't seems to be supported by vue triggering Uncaught DOMException: Operation is not supported ... createElement #13109

@vemonet

Description

@vemonet

Vue version

3.5.13

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-pbrkv3zs?file=src%2Fcomponents%2FHelloWorld.vue

Steps to reproduce

In the reproduction link open the terminal to see the error Uncaught DOMException: Operation is not supported ... createElement

Otherwise locally:

  1. Create a project with https://vuejs.org/guide/quick-start npm create vue@latest
  2. Install my web component with npm i --save @sib-swiss/sparql-editor
  3. Import it and use it in the welcome page
<script setup lang="ts">
import '@sib-swiss/sparql-editor'
</script>

<template>
  <sparql-editor endpoint="https://www.bgee.org/sparql/"></sparql-editor>
  ....
</template>

Start in dev with npm run dev

What is expected?

An editor for SPARQL queries should be displayed using this web component.

What is actually happening?

Nothing displayed

Get warning:

[Vue warn]: Failed to resolve component: sparql-editor
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <TheWelcome > 
  at <HomeView onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <RouterView > 
  at <App>

And error:

Uncaught DOMException: Operation is not supported
    createElement runtime-dom.esm-bundler.js:37
    mountElement runtime-core.esm-bundler.js:4846

Following the first link brings to the const el here:

createElement: (tag, namespace, is, props) => {
    const el = namespace === "svg" ? doc.createElementNS(svgNS, tag) : namespace === "mathml" ? doc.createElementNS(mathmlNS, tag) : is ? doc.createElement(tag, { is }) : doc.createElement(tag);
    if (tag === "select" && props && props.multiple != null) {
      el.setAttribute("multiple", props.multiple);
    }
    return el;
  },

The error seems to point at a createElement that is not supported on the DOM, which is unfortunate because this is probably the most basic operation one will want to do on the DOM

Note I am creating a <style> element: document.createElement("style") which is really a common practice when building standard web component. Not sure if this could conflict with the built in vuejs style element?

I am not doing anything really fancy in my web component, you can see most of the code here: https://github.com/sib-swiss/sparql-editor/blob/main/packages/sparql-editor/src/sparql-editor.ts

System Info

System:
    OS: macOS 14.4.1
    CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
    Memory: 19.77 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 23.9.0 - ~/.nvm/versions/node/v23.9.0/bin/node
    Yarn: 1.22.22 - /usr/local/bin/yarn
    npm: 11.2.0 - ~/.nvm/versions/node/v23.9.0/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  Browsers:
    Zen browser and chromium
  npmPackages:
    vue: ^3.5.13 => 3.5.13

Any additional comments?

Someone managed to make it work by wrapping it in a <v-html>, so it works, just not when vue tries to compile it

It's quite frustrating to see that 10+ years old "standard web components" are still so poorly supported by mainstream frameworks 😭 I hate to give it all to 1 framework, and for this web components should be a decent option, but it seems like there is always a problem. I even did the extra work to write it in vanilla JS no framework to avoid weird walled gardens, but here we go getting the most basic DOM manipulation function not supported by vue 😭

Also I do not use shadowDOM because I know how poorly it is supported by most JS frameworks and hated by frameworks devs

Vue boasts to perfectly supports web component (https://vuejs.org/guide/extras/web-components), so I guess it should just be a weird peculiarity with one of my createElement, and not something related to custom elements themselves?

Also the fact I need to do some weird config in compilerOptions.isCustomElement is really not ideal from the start. Web components are there for more than 10 years, and the rule is clear: if it's lower case with at least 1 dash it's a custom element. There is no reason to ask devs do those weird additional config for each web component they would like to use.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions