JSFiddle - React, Tailwind, and code Playground

HTML

<p>If you create a custom element by injecting it with <code>innerHTML</code>, the <code>createdCallback</code> is able to access the element's attributes, which in some cases is essential for configuration. As far as I can tell, there's no way to pass in the same configuration data when creating elements programmatically, making custom elements profoundly difficult to work with in the context of (say) a client-side view library.</p>

<p>Am I being uncharitable to suggest that this is something of a design flaw?</p>

<main></main>

<pre class='error'></pre>

CSS

body {
    font-family: 'Helvetica Neue', arial, sans-serif;
    font-weight: 200;
    color: #353535;
}

h1, h2, h3, h4, h5, h6 {
    font-weight: 200;
}

main {
    padding: 0.5em;
    background: #ddd;
}

.error {
    color: #d00;
    font-family: monospace;
}

JavaScript

var xSocketProto = Object.create( HTMLElement.prototype );
xSocketProto.createdCallback = function () {
    var node = this;
    var url = this.getAttribute( 'url' );
    console.log( 'url', url );
    this.socket = new WebSocket( url );
    
    this.socket.onmessage = function ( event ) {
        node.innerHTML += 'message received: <strong>' + event.data + '</strong></br>';
    };
    
    this.socket.onopen = function () {
        console.log( 'opened socket' );
        this.send( 'test message' );
    };
    
    // some code goes here...
};

document.registerElement( 'x-socket', {
    prototype: xSocketProto
});

var main = document.querySelector( 'main' );

main.innerHTML = '<x-socket url="wss://cptuatapp03:4040/"></xsocket>';

var pre = document.querySelector( 'pre' );
window.onerror = function ( err ) {
    pre.textContent += err;
};

var programmaticallyCreatedSocket = document.createElement( 'x-socket' );
programmaticallyCreatedSocket.setAttribute( 'url', 'wss://cptuatapp03:4040' ); // too late