Using code components in Plasmic Studio

You can use custom React components—from your own codebase or imported from npm libraries—directly as building blocks in Plasmic Studio.

This is a powerful capability that enables teams to:

  • Use their existing design system.
  • Show dynamic data.
  • Use components of arbitrary complexity and behavior.
  • Introduce interactions, effects, and functionality not yet built into Plasmic Studio.

You can seamlessly interleave code components and content you’ve designed in Plasmic Studio, using slots.

Set up app hosting

To use code components in Plasmic Studio, you need to first set up a project to use app hosting.

Register code components from the host application

The host application can use the method registerComponent from @plasmicapp/host to register React code components:

function registerComponent(component: React.ComponentType<any>, meta: ComponentMeta): void;

The first parameter component is the component you want to register and use in the Studio.

The second parameter meta is an object containing metadata about the component:

  • meta.name: A unique string name used to identify that component. Each component should be registered with a different meta.name, even if they have the same name in the code.

  • meta.props: An object describing the component properties to be used in Studio. For each prop, there should be an entry meta.props[prop].

    • meta.props[key]: The type of the property identified by key. The types are specified in the form of PropType (see more information below).
  • meta.importPath: The path to be used when importing that component in the generated code. It can be the name of the package that contains the component, or the path to the file in the project (relative to the root directory).

  • meta.displayName: The name to be displayed for the component in Studio. Optional: if not specified, meta.name is used.

  • meta.importName: The javascript name to be used when generating code. Optional: if not provided, meta.name is used.

  • isDefaultExport: Whether the component is the default export from that path. Optional: if not specified, it’s considered false.

  • classNameProp: The prop that expects the CSS classes with styles to be applied to the component. Optional: if not specified, Plasmic will expect it to be className.

  • refProp: The prop that receives and forwards a React ref. Plasmic only uses ref to interact with components in the editor, so it’s not used in the generated code. Optional: If not provided, the usual ref is used.

Notice that Plasmic uses className to style components, so if the it doesn’t accept CSS classes, the component might not be able to receive styles from the Studio.

Similarly, Plasmic uses React refs in the Studio by default, so function components are expected to be wrapped in React.forwardRef. However, it’s also possible to setup the host app to work with components that don’t expose refs - see the function code components topic.

Property types

PropType is used to describe the types of the properties registered with the component. It can be:

  • "string", "boolean", "number" for those javascript primitive types;

  • "object" for arbitrary JSON values, including objects and arrays;

  • "slot" for props that expect React elements, which will be treated as Plasmic slots;

  • Or an object obj containing:

    • obj.type: Any of the above strings, specifying the types, or "choice" when the type is defined by a list of options;
    • obj.options: Only applicable to "choice" type. Expects a list of strings containing the options to be passed to the prop;
    • obj.defaultValue: The default value that should be provided to the prop. Optional: If not present, and no value is passed when the component is instantiated, Plasmic won’t provide any value. Not applicable to "slot" type;
    • obj.editOnly: A boolean indicating whether the values passed to that prop should be used in the generated code. If true, the values will be used only in the editor, and might optionally be mapped to another prop via obj.uncontrolledProp. Optional: if not specified, it’s assumed to be false. Not applicable to "slot" type;
    • obj.uncontrolledProp: Only applicable when obj.editOnly is true. Should contain a string containing the name of prop that should receive the values in the generated code. Optional: if not provided (and obj.editOnly is true), then the values set in the editor will not be provided to any prop in the generated code;
    • obj.allowedComponents: Only applicable to "slot" type. A list of strings containing the unique names (meta.name) of the components that might be passed into this slot. For example, if a Menu only expects children of type MenuItem, it would contain ["MenuItem"]. Optional: if not provided, any component or element can be provided to the slot in the editor.

Examples

Use code components in Studio

Once the components are registered, you will be able to use them in your project—no different from any other component created in Plasmic!

Just like imported components, code components cannot be edited in Plasmic Studio (only instances of it can be customized).

Applying global themes / contexts to code components

The global CSS styles present in the host page are applied to the code components. For themes that are provided using React contexts, those can be provided when rendering PlasmicCanvasHost in the host page:

<ThemeContext.Provider>
<PlasmicCanvasHost />
</ThemeContext.Provider>

Any component instances used in your Plasmic designs will have access to the context as per usual.

Detecting when the component renders in the Editor

You might want to disable some functionality inside the component when editing it in Plasmic—for example, disable slow scroll animations or certain effects. For that reason, we provide a React context PlasmicCanvasContext whose value is true only when the component is rendering in the Editor.

const inEditor = useContext(PlasmicCanvasContext);
return inEditor ? <MyComponent /> : <MyComponent animated />;