Custom Component Registration does not work with bare metal React

I have discovered that you cannot register custom components if you are using React without a framework. The documentation is completely wrong on this point.

The relevant documentation is here: Registering Custom Components

Here is my prototype code that I created…

import { useEffect, useState } from "react";
import { BuilderComponent, BuilderContent, builder, useIsPreviewing, Builder } from "@builder.io/react";
import FourOhFour from "./FourOhFour";

// Put your API key here
builder.init("xxxxx");

// Register components

const Heading = (props: { title: string }) => (
  <h1>{props.title}</h1>
)

Builder.registerComponent(Heading, {
  name: "Heading",
  inputs: [
    {
      name: "title",
      type: "string",
      defaultValue: "Hello World"
    }
  ]
});

// set whether you're using the Visual Editor,
// whether there are changes,
// and render the content if found
export default function CatchAllRoute() {
  const isPreviewingInBuilder = useIsPreviewing();
  const [notFound, setNotFound] = useState(false);
  const [content, setContent] = useState(null);

  // get the page content from Builder
   useEffect(() => {
    async function fetchContent() {
      const content = await builder
        .get("page", {
          url: window.location.pathname
        })
        .promise();

      setContent(content);
      setNotFound(!content);

      // if the page title is found, 
      // set the document title
      if (content?.data.title) {
       document.title = content.data.title
      }
    }
    fetchContent();
  }, [window.location.pathname]);
  
  // If no page is found, return 
  // a 404 page from your code.
  // The following hypothetical 
  // <FourOhFour> is placeholder.
  if (notFound && !isPreviewingInBuilder) {
    return <FourOhFour/>
  }

  // return the page when found
  return (
    <>
      {/* Render the Builder page */}
      <BuilderComponent model="page" content={content!} />
    </>
  );
}

This is a source file in a prototype project create like so…|

$ npx create-react-app lpp4 --template typescript
$ cd lpp4
$ npm install "@builder.io/react"
$ npm install "@builder.io/sdk"
$ npm install "@builder.io/dev-tools"

If I run the prototype, the builder page is rendered perfectly…

Here is my builder.io editing page…

As you can see there are no registered custom components. There should be a “Heading” component.

So there is a theme here. Builder.io integration simply does not work properly with React without a framework. You are on a fool’s errand if you try to integrate Builder.io without a framework. The client-side plug-in is apparently critical to completing the integration. Every single Builder.io integration prototype I have built with Nextjs has worked fine. Conversely every single Builder.io integration I have built with React without a framework has had strange problems.

In conclusion you need a supported React framework to integrate Builder.io. Fine. Except that the documentation says you can integrate without a framework. I’ve squandered a 100 hours now trying to get this to work. Hours that I cannot bill my client…because I’m just not going to bill him for hours spent working on an integration that I told him would be easy (Integrate in 3 minutes!) and turns out to be a nightmare.

The reason I am not working in Nextjs is that I am working on a huge legacy website. Converting the entire thing to Nextjs is a non-starter.

What I have concluded I have to do to integrate Builder.io is to create a completely separate satellite site implemented in Nextjs. Whenever the client wants to edit a page, I will redirect him to the new site where Builder.io will work properly. It is going to be a lot of work to create this satellite site…work that I did not bid. Hours that I will have to eat. So I am really, really not happy.