Regstering web components for use in Builder's Visual Editor

Registering custom elements with Builder is a great way to get support of custom blocks in Builder for any framework.

Let’s say we have a webcomponent called my-hero that takes a title and susbtitle like so

<my-hero title="Hello world" substitle="Lorem ipsum"></my-hero>

That you defined in your code something like:

class MyHero extends HTMLElement { /* ... */ }

customElements.define('my-hero', MyHero)

You can register it in your code:

<script>
// When the SDK loads
window.builderWcLoadCallbacks = [
  (context) => {
    // Register each component
    context.Builder.registerComponent(null, {
      tag: 'my-hero',
      inputs: [ 
        { name: 'title', type: 'string', defaultValue: 'Hello world' },
        { name: 'subTitle', type: 'string', defaultValue: 'Lorem ipsum' }
      ]
    })
  }
];
</script>

You can see more on our import types supported here - just note that for webcomponents we only support primitive elements (text, number, boolean, etc) and not deep objects and arrays (lists, maps, etc)

To render your content, see our webcomponents SDK docs

<builder-component model="page" api-key="YOUR_KEY">
  <!-- HTML here will display while your content is loading, e.g. put a gif here, or leave empty -->
</builder-component>
1 Like

This looks promising but I feel like there needs to be more documentation or examples showing how to use web components in Builder. It would be great if there was a web component example in

2 Likes

@sublimina Thank you for the feedback! We are continuing to build out our documentation within both github and our documentation hub.

For more information specifically on web components check out: Builder.io Webcomponents API - Builder.io

There is a bit more information as well as links to any number of articles about setting up your builder site. Check it out and let us know if you have any specific questions or areas we can help with!

hello @TimG

I would like to ask that is there any complete example of builder webcomponent that we can implement?

I have refered this Builder.io Webcomponents API - Builder.io but facing issues…

hi @rinkal what exact issues are you encountering? The top of this article and then the API doc has some basic examples, but for more robust examples it might be helpful to understand your exact use case!

I am creating web component in order to get custom component data via HTML API. but when i tried that example i am getting some reference errors like customElements, window, HTMLElement not defined…

please correct me if i am on wrong track.

Thanks for your kind response!!

hi @rinkal if you could share your code snippet so I can see exactly how you are trying to achieve this I would be happy to advise!

Sure!! currently i am trying simpler example in my next APP. My requirement is i want to fetch custom component data via HTML API. Also i have one query that is this web component will be available to drag and drop in builder dashboard?

This is testpage.js file in pages directory in my next app.

import React from 'react';
import { BuilderComponent, builder, useIsPreviewing, Builder } from '@builder.io/react';
import DefaultErrorPage from 'next/error';
import Head from 'next/head';
import loadable from '@loadable/component';
import * as ReactDOM from 'react-dom/client';


class MyHero extends HTMLElement { 
  constructor() {
    super();
  }
  
  connectedCallback() {
    this.innerHTML = `<h1>Hello world!</h1>`
  }
}

customElements.define('my-hero', MyHero)

export default function TestPage() {
    return(
      <>
        <Head>
          <title>Test</title>
          <script src="https://unpkg.com/@webcomponents/custom-elements"></script>
          <script async src="https://cdn.builder.io/js/webcomponents"></script>

          <script>
          {
          
          window.builderWcLoadCallbacks = [
            (context) => {
              // Register each component
              context.Builder.registerComponent(null, {
                name: 'My Hero',
                tag: 'my-hero',
                inputs: [ 
                  { name: 'title', type: 'string', defaultValue: 'Hello world' },
                  { name: 'subTitle', type: 'string', defaultValue: 'Lorem ipsum' }
                ]
              })
            }
          ]
          
          }

          </script>
        </Head>
        <my-hero title="Hello world" substitle="Lorem ipsum"></my-hero>
      </>

    )
  }

  

Hey @rinkal, this web components pattern is for when you are using our Web Components API, usually when you don’t have a more modern framework available in your app.

I see your app is Built in React and possibly NextJs, and the good news is that the use of , builderWcLoadCallbacks, etc are all not necessary within the React SDK and we have a number of features build into the SDK to streamline and simplify your implementation.

I would recommend checking out our React Custom Components documentation for more info, but more likely your file could be cleaned up to look something like this:

import React from 'react';
import { Builder } from '@builder.io/react';
import Head from 'next/head';


Builder.registerComponent(MyHero, {
   name: 'My Hero',
   inputs: [ 
       { name: 'title', type: 'string', defaultValue: 'Hello world' },
       { name: 'subTitle', type: 'string', defaultValue: 'Lorem ipsum' }
     ]
   });

class MyHero extends React.Component { 
 render() {
   return (
       <h1>{this.props.title}</h1>
       <h2>{this.props.subTitle}</h2>
   )
}

export default function TestPage() {
   return(
     <>
       <Head>
         <title>Test</title>
       </Head>
       <MyHero title="Hello world" subTitle="Lorem ipsum"></MyHero>
     </>
   )
 }

Would this work for you? We also have a number of React and NextJs starters, such as our Next Js Simple starter or our React Design System starter that each of examples of registering custom components

Let me know if this answers your questions!

Hello @TimG

I am really thankful for your response.

Yes, this is worked for creating custom component, but this custom component data will not be accessible via Html api.

1 Like