Overriding props on elements

Override props allow you to customize a component’s tree of elements exactly as you see fit to make your component come alive. You can modify the props used for each element, attach event handlers, override rendered content, wrap elements in other React components, and more. We want you to have total control in making the element tree exactly what you want.

Furthermore, the API of generated components offers a clean way to pass in overrides so that functionality is easily preserved across design iterations, as long as users keep the same prop names across redesigns.

For more details, see the reference API.

Naming elements in Studio

The component as designed in Plasmic creates a tree of elements that corresponds to the tree of layers you see in Plasmic.

Double click on the element in the left pane of the Studio to give the element a name.

Naming an element

Note that the top level node is always called root.

Override props in code

You reference the element you want to override by its name; so if you want to override an element, you must first name that element in Plasmic.

For example, for the Button component, you might want to override its root element to attach click handlers:

Copy
<PlasmicComponent
component={'Button'}
componentProps={{
root: {
props: {
onClick: () => alert('I got clicked!')
}
}
}}
/>

Or maybe you want to render the Button as a link instead:

Copy
<PlasmicComponent
component={'Button'}
componentProps={{
root: {
as: 'a',
props: {
href: 'https://plasmic.app'
}
}
}}
/>

The object you pass into the named node (“root”) above is the “Override object”. The Override object supports the following properties; you can mix and match them as needed:

props

Object of props to use for that element. Note that the element may be a normal HTML tag — in which case you can pass in HTML attributes — or a component — in which case you can pass in component props. For example,

Copy
{
props: {
title: user.name,
onClick: () => ...,
// etc.
}
}

as

The React.ElementType to use to render this element. This can be an HTML tag like “a” for links, or a React component. This element will then be rendered with that element type. For example,

Copy
{
as: "a",
props: {
href: ...
}
}

render

A function that takes in the props and the component type that would be rendered, and returns a ReactNode. Doing this will completely replace this element with whatever is returned from the render function.

For example, this is a no-op (will behave as if no render function was specified):

Copy
{
render: (props, Component) => <Component {...props} />;
}

You can adjust the rendering in various ways:

Copy
{
render: (props, Component) => (
<Wrapper>
<Component className={props.className} value={value} onChange={handleChange} />
</Wrapper>
);
}

You can swap in completely different content for this element:

Copy
{
render: (props, Component) => <TotallyDifferentComponent />;
}

You can also return null if you don’t want to render this element at all:

Copy
{
render: (props, Component) => null;
}

If you pass in a render function, then props and as are ignored.

wrap

A function that takes in the rendered ReactNode for this element, and returns another ReactNode. This is useful if you just want to wrap this element in something, like a context provider. For example,

Copy
{
wrap: node => <Context.Provider value={}>{node}</Context.Provider>
}

wrapChildren

A function that takes in the rendered children for this element, and returns another ReactNode. This is useful if you want to append or prepend some custom content as a child of this element. For example, to implement an accessible “checkbox”, you may want to sneak in a visually hidden input element that’s not actually in the design:

Copy
{
// insert a visually hidden checkbox input as the first child
wrapChildren: (children) => (
<>
<input className="visually-hidden" type="checkbox" />
{children}
</>
);
}

If you are planning to iterate over children, note that Plasmic-generated code will sometimes wrap elements in React.Fragments. Therefore, instead of using React.Children.map(), you should consider using something like react-keyed-flatten-children, which will flatten fragments for you.

Override object shorthands

Instead of passing in a full Override object as specified above, you can instead use one of these shorthands:

  • An object of prop overrides — if you pass in an object without any of the known keys above (props, as, render, wrap, and wrapChildren), we interpret that object as just a props override, equivalent to passing in {props: …}.
  • A ReactNode — we interpret this as the children override, equivalent to {props: {children: …}}.
  • A function — we interpret this as the render override, equivalent to {render: …}.

Root override props

Any additional props you pass in are interpreted as an override for the root element. For example, instead of using the root prop as we did before, we can directly set the overrides:

Copy
<PlasmicComponent
component={'Button'}
componentProps={{
// This is interpreted as a prop override for the root element
onClick: () => alert('I got clicked!')
}}
/>
Was this page helpful?

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