Creating Custom Input Types

I am looking for instructions on how to create a custom input type that I can use on components and or models so that I can define a common set of input fields once and re-use them.

For example, here is the definition of a component I have created that has a standard set of input fields to help creating links to content within the CMS. Rather than having to drag in this component as a child to other components I want to be able to define this as a custom input type (similiar to how the Cloudinary plugin defines the cloudinaryImageEditor type).

Builder.registerComponent(
  dynamic(() => import("@/components/navigation/cmslink")),
  {
    name: "CMS Link",
    inputs: [
      { name: "Label", type: "string", defaultValue: "Link Text" },
      {
        name: "type",
        type: "string",
        enum: ["page", "blog", "url", "text"],
        defaultValue: "page",
      },
      {
        name: "linkPage",
        type: "reference",
        model: "page",
        friendlyName: "Destination",
        showIf: `options.get('type') === 'page'`,
      },
      {
        name: "linkBlog",
        type: "reference",
        model: "blog",
        friendlyName: "Destination",
        showIf: `options.get('type') === 'blog'`,
      },
      {
        name: "linkUrl",
        type: "string",
        friendlyName: "Destination",
        showIf: `options.get('type') === 'url'`,
      },
      {
        name: "linkText",
        type: "string",
        friendlyName: "Destination",
        showIf: `options.get('type') === 'text'`,
      },
    ],
  }
);

Has anyone done something like this before / could you provide examples of how to do this? My goal would be to be able to define this custom InputType named ‘cmsLink’ and then use it in registering a component like this:

Builder.registerComponent(
  dynamic(() => import("@/components/helloworld")),
  {
    name: "Hello World",
    inputs: [
      {
        name: "type",
        type: "cmsLink",
      },
      {
        name: "linkText",
        type: "string",
      },
    ],
  }
);

Note, I am working in NextJS

2 Likes

Hello @jhs129,

To create a custom input type in Builder.io that can be reused for components and models, you need to create a custom plugin.

  1. Begin by setting up a directory for your plugin, initialize the project, and install necessary dependencies like @builder.io/app-context and @builder.io/react.
  2. Use Builder.registerEditor() to define your custom input type. This function takes an options object with a name, the component that will act as the editor, and optional configuration options.
    • Your custom type editor should be a React component that handles the input logic. It should receive value and onChange props to manage the data.

Here is an example:

Feel free to let us know if you have any further questions.

Best regards,

Hi Manish-

Thanks for providing this update. This gives a good example of how to create a plugin but it’s unclear how exactly I would create the custom input type within the plugin. Can you provide a bit more clarity on how to do specifically that?

Thanks,
John

Hello @jhs129,

To register your custom input type, use the Builder.registerEditor() method. This method requires an options object that includes name, component, and optional options. Once registered, your custom type will be available throughout the Builder’s Visual Editor. It can be utilized for custom component inputs, targeting content, model fields, and symbol inputs.

Here is an example:

Yes, you can absolutely make custom input types within Builder.io! Defining your custom input type, like cmsLink, and then using it inside your component registration is the key. To do that you would need to create a custom input component and pass it to Builder.registerInputType. Then you can refer it in your components as you have already shown. I think it’s something akin to creating your own Cloudinary input, but for your CMS link setup. I haven’t seen a direct example, but that’s what you’d do.