Component substitution in codegen

(See also component substitution in the Headless API.)

You can use existing code components or design systems with Plasmic.

One approach: you can drag and drop your code components directly in Plasmic Studio.

An alternative approach is to create placeholder components in Plasmic Studio, and have them swapped out for the real thing at build or render time. You may want this if your component is very heavyweight, and you don’t need it in Plasmic Studio in either editing or preview modes.

This video shows an example of performing component substitution in codegen:

The workflow is:

  1. Create a design-time placeholder for the existing code component you’re interested in. This is just for use in the Studio, and can be as accurate as you want it to be in mirroring what the real code component looks like.
  2. In code, substitute the existing code component for the design-time placeholder.
  3. Optionally use props, especially meta props and slots, to configure the behavior of the code component.

Performing component substitution

For instance, if you want to use a Google Maps widget:

  1. Paste a static screenshot of a Google Maps widget into your project, and turn it into a component called “GMaps.” Use this component wherever you want a real Google Maps widget.

  2. Add substitutions to the PlasmicLoader configuration in your initialization file:

    Copy
    import { MyHome } from './components/MyHome';
    // In your plasmic config
    const PLASMIC = initPlasmicLoader(...);
    PLASMIC.substituteComponent(MyHome, "Home");

    Then add the substituting component:

    Copy
    // src/components/GMaps.tsx
    import { GoogleMap, LoadScript } from '@react-google-maps/api';
    interface GMapsProps {
    location: string;
    className?: string;
    }
    function GMaps({ location, className }: GMapsProps) {
    // We render a real <GoogleMap/> rather than <PlasmicComponent component="GMaps"/>.
    const [lat, lng] = useResolvedLocation(location); // your own hook
    return (
    <LoadScript googleMapsApiKey="...">
    <GoogleMap center={{ lat, lng }} mapContainerClassName={className} zoom={10} />
    </LoadScript>
    );
    }
  3. In Plasmic Studio, on the GMaps component, add a meta prop location of type text. Plasmic Studio users can use this to identify a concrete location that the real Google Maps widget can read. See more on this below.

(Side note: @react-google-maps has blocking JS and/or layout shift on load. We recommend lazily loading the component on scrolling into view, or using a performance-optimized alternative such as Pigeon Maps.)

Adding component props

Components are customized via props. How do we enable the design-time placeholder component in Plasmic Studio to specify props to the code component it’ll be substituted by?

Meta props

You can explicitly add meta props to the placeholder component. Then, from any instance, you can pass a value for the prop. These are not used or reflected in any way in the design-time placeholder component; you’re simply attaching metadata to the component instance.

Later, when the code component is attached, these props will be forwarded to it.

The meta props have simple data types like text and number. As such these are appropriate when you have some simple data to pass in. Examples of this include:

  • a Google Maps widget has some location prop (as we’ve seen above).
  • a Product Card has a productId prop.
  • a Video component has a url prop.

Slots

However, some components have children or similar props, which take ReactNodes rather than data types like text or number.

Examples of this include:

  • a Button takes a children prop for its main text/content.
  • a Blog Post component takes a title and children (main body content).

For these, you would pass in other visual elements for the props (i.e. they take ReactNodes). So in your Blog Post placeholder component, you should create slots named children and title. Then you can visually manipulate the elements as usual in the Plasmic Studio editor.

Was this page helpful?

Have feedback on this page? Let us know on our forum.