Root Configuration
The root is the top-level component within Puck. It:
- Renders a single wrapper around your other components. This can be overwritten with a
renderfunction. - Stores meta data, like the page title. This can be extended with
fields.
Configuring the root is similar to configuring components.
The root render function
Use the root parameter to specify a render function:
const config = {
components: {
HeadingBlock: {
render: () => {
return <h1>Hello, world</h1>;
},
},
},
root: {
render: ({ children }) => {
return <div>{children}</div>;
},
},
};The root render function will wrap all of the components. children is a node containing the nested components.
If you don't render children, your components will not be rendered (unless you're defining custom root DropZones).
Example output
Given a minimal data payload containing one HeadingBlock
{
"content": [
{
"type": "HeadingBlock",
"props": {
"id": "HeadingBlock-1234"
}
}
],
"root": {}
}the example config will render HTML nodes like this:
<!-- root render -->
<div>
<!-- HeadingBlock render -->
<h1>Hello, world</h1>
<!-- Remining nodes -->
</div>Adding fields
Root fields provide user input to the root render method, and can be used to store metadata.
By default, root is configured with a title text field:
const config = {
// ...
root: {
render: ({ children, title }) => {
return (
<div>
<h1>{title}</h1>
{children}
</div>
);
},
},
};We can override the default field configuration by providing custom Fields to the fields parameter:
const config = {
// ...
root: {
fields: {
title: { type: "text" }, // We need to redefine the `title` field if we want to retain it
description: { type: "textarea" },
},
render: ({ children, title, description }) => {
return (
<div>
<h1>{title}</h1>
<p>{description}</p>
{children}
</div>
);
},
},
};When the user modifies the inputs, the editor will produce a data payload like this:
{
"content": [
// ...
],
"root": {
"props": {
"title": "Hello, world",
"description": "Lorem ipsum"
}
}
}TypeScript
Generic types can be passed to the Config type to strictly type your root configuration:
import type { Config } from "@measured/puck";
type RootProps = {
description: string;
};
const config: Config<{}, RootProps> = {
// ...
};Setting default props
Provide an object to the defaultProps parameter to configure default props for the root fields:
const config = {
// ...
root: {
fields: {
title: { type: "text" },
description: { type: "textarea" },
},
defaultProps: {
title: "Hello, world",
description: "Lorem ipsum",
},
render: ({ children, title, description }) => {
return (
<div>
<h1>{title}</h1>
<p>{description}</p>
{children}
</div>
);
},
},
};Unlike default parameters (opens in a new tab), defaultProps are stored in the data payload and will populate the Puck fields.