Web components on Observable

Hi,

I have not found any post on this, nor any example on the public notebooks. My question is how do we import web components on an observable notebook ? The standard implementation on a web page is to import the code in a js script, however that does not seem to be the way in observable. Hence my question ? For example, how it would be done for those components ?
https://lit-element-bootstrap.dev/getting-started

Thanks a lot,
Sebas

2 Likes

Here’s a short demo:

To import another component, go to https://unpkg.com/@lit-element-bootstrap/[package name]?module and copy the resulting URL after it redirects to the actual file name & version.

There’s another working example of Web Components here:

There are a couple of caveats, though.

The first is that Web Components doesn’t expose any way of removing or replacing a custom element definition. There’s customElements.define, and that’s it. That means that if you ever want to change your custom element definition, you have to reload the entire page. This goes against the grain of Observable, which uses dataflow to re-evaluate cells automatically.

The second is that Web Components cannot be statically analyzed. Consider this cell:

 html`<my-element mood="happy"></my-element>`

Observable has no way of knowing that the <my-element> custom element is defined by the cell called MyElement. And hence you could be creating those custom elements before the custom elements are defined. That might not be a problem—the browser will correct the display for custom elements that already exist in the DOM—but if you depend on certain runtime behavior in the cell that’s creating the elements, it might be surprising.

You can avoid the second caveat by making the dependency explicit by referencing the MyElement class, but it’s a little awkward:

MyElement, html`<my-element mood="happy"></my-element>`
2 Likes

Thanks both ! I do understand the problem. Does that mean that other approaches like Vue.js or React are preferred or more adapted to observable ?

Yep! Here’s a notebook for Vue:

And one for React:

But most of the time you’ll be just fine with the native DOM APIs.