Livestream: Best practices for building with GenUI | 5/22

Announcing Visual Copilot - Figma to production in half the time

Builder logo
builder.io
Contact SalesGo to App

Livestream: Best practices for building with GenUI | 5/22

Announcing Visual Copilot - Figma to production in half the time

Builder logo
builder.io

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

When registering custom components to use within data entries, add the showIf key to inputs to dynamically modify what attributes are editable for the component.

  • Dynamically hide and show inputs for a registered component.
  • Leverage the options object for dynamic statements.

This tutorial results in a CustomHeader registered component that displays banner text with an optional background image. Inputs dynamically adjust based on the component's state.

An example video demonstrating this functionality is below.

To complete this tutorial, you need:

Begin by creating a new registered component in your codebase.

Create a new CustomHeader.tsx file. The location of this file depends on your file structure, but it should be accessible from one of your connected pages.

Within the file, create the shell of your registered component.

"use client";
import type { RegisteredComponent } from "@builder.io/sdk-react";

export function CustomHeader() {
  return (
    <h1>My Custom Header</h1>
  );
}

export const customHeaderInfo: RegisteredComponent = {
  component: CustomHeader,
  name: "CustomHeader"
};

This file:

  • imports the RegisteredComponent type from Builder's SDK
  • creates a new component called CustomHeader with an h1 element inside of it
  • exports the registered component as an object, referencing the component and providing a name for it

Within one of your integrated pages, import your registered component.

import { customHeaderInfo } from "../../components/CustomHeader";

To confirm your component has been registered with Builder:

  1. Open up your integrated page within Builder.
  2. Open the Custom Components panel within the Insert tab.
  3. Drag the Custom Header block to an available space on your page.

If working correctly, you should see your h1 element's text appear on your page.

Tip: As you continue in the tutorial, you may notice some changes from your registered component do not immediately reflect within Builder.

While Builder watches for stylistic changes, updates to the exported registered component may require a refresh of your Builder content entry within the browser.

Next, add styles to your component so that it appears as you'd like. For now, the colors and text within the component remain static.

Replace the CustomHeader component with the code below. This code adds a small amount of styling to the header.

export function CustomHeader() {
  return (
    <h1
      style={{
        background: "#CCCCCC",
        lineHeight: 1.4,
        padding: "120px 50px 50px",
      }}
    >
      <span
        style={{
          backgroundColor: "black",
          color: "white",
          display: "inline",
          padding: "0.5rem",
          boxDecorationBreak: "clone",
        }}
      >
        My Custom Header
      </span>
    </h1>
  );
}

Return to your integrated page on Builder. There, you should see your component is updated.

Add inputs to your registered component, to adjust the style and text of your header from within Builder's Visual Editor.

First, define the parts of your component you wish to be dynamic within your registered component by doing the following:

  1. Add an inputs key to the registered component. The value should be an array.
  2. Within your inputs array, create an object with the following keys: name, type, and defaultValue. For more details on input types, see Input types for custom components.
  3. Fill in the values for those keys for each adjustable value within your registered component.

In the code example below, the title is made adjustable along with all colors within the header.

export const customHeaderInfo: RegisteredComponent = {
  component: CustomHeader,
  name: "CustomHeader",
  inputs: [
    { name: "title", type: "text", defaultValue: "My Title" },
    { name: "titleColor", type: "color", defaultValue: "#FFFFFF" },
    { name: "titleBackgroundColor", type: "color", defaultValue: "#000000" },
    { name: "backgroundColor", type: "color", defaultValue: "#CCCCCC" },
  ],
};

Now, use those inputs within your component. First, define a TypeScript interface for your components props, as seen in the code example below.

interface CustomHeaderProps {
  title: string;
  titleColor: string;
  titleBackgroundColor: string;
  backgroundColor: string;
}

Next, access the inputs through props within your component. Replace hardcoded values with prop values.

export function CustomHeader({
  title,
  titleColor,
  titleBackgroundColor,
  backgroundColor,
}: CustomHeaderProps) {
  return (
    <h1
      style={{
        background: backgroundColor,
        lineHeight: 1.4,
        padding: "120px 50px 50px",
      }}
    >
      <span
        style={{
          backgroundColor: titleBackgroundColor,
          color: titleColor,
          display: "inline",
          padding: "0.5rem",
          boxDecorationBreak: "clone",
        }}
      >
        {title}
      </span>
    </h1>
  );
}

Your registered component should look the same when first added to your content entry. However, within the Options tab, you can now adjust the title and various colors of the header.

Tip: Remember, you might need to refresh to see your changes. If your component does not automatically update, Remove the component and then add a fresh copy from the Custom Components panel.

You now have a functional registered custom component that is editable within Builder. Now it's time to transform the registered component by adding conditional inputs that are dependent on the values of other inputs.

First, add new inputs that relate to setting a background image within the header as opposed to just a single color.

In the code example below, three new inputs are added to the registered component.

export const customHeaderInfo: RegisteredComponent = {
  component: CustomHeader,
  name: "CustomHeader",
  inputs: [
    { name: "title", type: "text", defaultValue: "My Title" },
    { name: "titleColor", type: "color", defaultValue: "#FFFFFF" },
    { name: "titleBackgroundColor", type: "color", defaultValue: "#000000" },
    { name: "backgroundColor", type: "color", defaultValue: "#CCCCCC" },
    // New inputs
    { name: "backgroundImage", type: "url", defaultValue: "" },
    { name: "backgroundPositionX", type: "text", defaultValue: "100%" },
    { name: "backgroundPositionY", type: "text", defaultValue: "25%" },
  ],
};

Next, update the TypeScript interface with these new inputs.

interface CustomHeaderProps {
  title: string;
  titleColor: string;
  titleBackgroundColor: string;
  backgroundColor: string;
  backgroundImage: string;
  backgroundPositionX: string;
  backgroundPositionY: string;
}

Then update your component to account for these new inputs. In the code below, if there is a value within the backgroundImage property, a background image is shown. Otherwise, the background color is shown.

export function CustomHeader({
  title,
  titleColor,
  titleBackgroundColor,
  backgroundColor,
  backgroundImage,
  backgroundPositionX,
  backgroundPositionY,
}: CustomHeaderProps) {
  return (
    <h1
      style={{
        background:
          backgroundImage !== ""
            ? `url(${backgroundImage}) ${backgroundPositionX} ${backgroundPositionY}`
            : backgroundColor,
        lineHeight: 1.4,
        padding: "120px 50px 50px",
      }}
    >
      <span
        style={{
          backgroundColor: titleBackgroundColor,
          color: titleColor,
          display: "inline",
          padding: "0.5rem",
          boxDecorationBreak: "clone",
        }}
      >
        {title}
      </span>
    </h1>
  );
}

Return to your Builder page and test out the new functionality for this registered component. When you add a background image to the input, you should see that background image replace the background color.

While the functionality of the registered component is working, the Options tab is a bit busy and confusing. When you are setting a background image, you should not need to also choose a background color.

To solve this, add the showIf property to specific inputs you wish to hide or show depending on what other values are present within the component. This requires changes to the registered component definition, not the actual component.

The value to showIf is a string, but it functions as a JavaScript expression. This expression is evaluated as true or false and determine whether or not the input should be displayed.

export const customHeaderInfo: RegisteredComponent = {
  component: CustomHeader,
  name: "CustomHeader",
  inputs: [
    { name: "title", type: "text", defaultValue: "My Title" },
    { name: "titleColor", type: "color", defaultValue: "#FFFFFF" },
    { name: "titleBackgroundColor", type: "color", defaultValue: "#000000" },
    {
      name: "backgroundColor",
      type: "color",
      defaultValue: "#CCCCCC",
      showIf: 'options.get("backgroundImage") === ""',
    },
    { name: "backgroundImage", type: "url", defaultValue: "" },
    {
      name: "backgroundPositionX",
      type: "text",
      defaultValue: "100%",
      showIf: 'options.get("backgroundImage") !== ""',
    },
    {
      name: "backgroundPositionY",
      type: "text",
      defaultValue: "25%",
      showIf: 'options.get("backgroundImage") !== ""',
    },
  ],
};

In the example above, the following has changed:

  • The backgroundColor, backgroundPositionX, and backgroundPositionY inputs all have the showIf key with a string expression.
  • The backgroundColor input is only shown if the value of the backgroundImage input is an empty string.
  • Alternatively, the backgroundPositionX and backgroundPositionY inputs will only be shown if the backgroundImage input is not an empty string.

The video below shows a background image being added to the custom component. When the image URL is added, the background color input disappears and two new inputs appear related to the positioning of the background image.

Within each of the showIf string values above, the options object is used to gain access to the values of all inputs on the current registered component.

The .get() method takes a string value that represents the name of the input. The value returned from the .get() method is the current value of the input.

For more details on what objects are available to you within the expression, see the showIf entry in Input types for custom components.

Visit Input types for custom components for more examples of what you can do with custom components and inputs. Or, see Child blocks in custom components to learn how to integrate Builder blocks into your custom components.

Was this article helpful?

Product

Visual CMS

Theme Studio for Shopify

Sign up

Login

Featured Integrations

React

Angular

Next.js

Gatsby

Get In Touch

Chat With Us

Twitter

Linkedin

Careers

© 2020 Builder.io, Inc.

Security

Privacy Policy

Terms of Service

Get the latest from Builder.io

By submitting, you agree to our Privacy Policy

  • Platform Overview

    AI Overview

  • Integrations

  • What's New

  • Figma to Code Guide

  • Composable Commerce Guide

  • Headless CMS Guide

  • Headless Commerce Guide

  • Composable DXP Guide

  • Design to Code

  • Blog

  • Knowledge Base

  • Community Forum

  • Partners

  • Templates

  • Success Stories

  • Showcase

  • Resource Center

    Glossary

© 2025 Builder.io, Inc.

Security

Privacy Policy

SaaS Terms

Compliance

Cookie Preferences

Gartner Cool Vendor 2024