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
render
function. - 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, defaultProps
are stored in the data payload and will populate the Puck fields.