Page Types, Templates and Custom Fields
Add custom fields
Add page-level custom fields to a page type and access their values inside bricks with usePageValues.
In this how-to, you'll learn how to add custom fields to a page type in React Bricks.
Custom fields are edited like sidebar controls, but they live at page level rather than inside a single brick.
Why custom fields are useful
Bricks are great for visual content, but sometimes a page also needs structured values that are not tied to one specific brick.
For example, a product page may need:
- a product SKU
- a product ID for external APIs
- a price
- a short subtitle
These values belong to the page as a whole, not to one individual block.
That is where custom fields help.
Custom fields are page-level sidebar controls
Custom fields are configured on the page type, not on a brick schema.
Conceptually, they work like brick sideEditProps, but at page level.
That means:
- editors edit them from the "page" UI tab
- their values belong to the page
- any brick on that page can read and render them
Docs reference: Custom Fields
Add customFields to a page type
Let's imagine a product page type.
We can add customFields like this:
{
name: 'product',
pluralName: 'products',
defaultStatus: types.PageStatus.Published,
customFields: [
{
name: 'productId',
label: 'Product ID',
type: types.SideEditPropType.Text,
},
{
name: 'price',
label: 'Price',
type: types.SideEditPropType.Number,
},
{
name: 'featured',
label: 'Featured',
type: types.SideEditPropType.Boolean,
},
],
}This works very much like sideEditProps on a brick.
Each field has:
name: the key used to store the valuelabel: the label shown to editorstype: the kind of control to render
Use custom field values inside a brick
To read page-level values inside a brick, use the usePageValues hook.
Docs reference: usePageValues
Here is a simple example:
const [page] = usePageValues()The returned page object contains page-level data, including:
page.customValuesSo you can read custom fields like this:
page.customValues.productId
page.customValues.price
page.customValues.featuredExample brick using usePageValues
Here is a simple example of a brick that reads a custom field:
import { Text, types, usePageValues } from 'react-bricks/frontend'
interface ProductHeroProps {
title: types.TextValue
}
const ProductHero: types.Brick<ProductHeroProps> = ({ title }) => {
const [page] = usePageValues()
return (
<div>
<Text
propName="title"
value={title}
placeholder="Product title..."
renderBlock={({ children }) => <h1>{children}</h1>}
/>
{page.customValues?.productId ? (
<p className="text-sm text-slate-500">
Product ID: {page.customValues.productId}
</p>
) : null}
</div>
)
}In this example, the brick displays the page-level productId custom field below the title.
Why usePageValues is powerful
Because the values live on the page, multiple bricks can read the same custom field.
For example:
- one brick may show the subtitle
- another brick may use the product ID to fetch external data
- another brick may render a badge if
featuredis true
So custom fields are a good way to combine structured page data with visual bricks.
Bind visual components to custom fields
Besides reading custom fields with usePageValues, you can also bind visual components directly to page-level custom fields.
Docs reference: Text: bind to meta data or custom fields
Instead of using propName, use customFieldName.
For example, a Text component can be bound directly to a page custom field:
import { Text, types } from 'react-bricks/frontend'
interface ProductHeroProps {
subtitle: types.TextValue
}
const ProductHero: types.Brick<ProductHeroProps> = ({ subtitle }) => {
return (
<Text
value={subtitle}
customFieldName="subtitle"
placeholder="Product subtitle..."
renderBlock={({ children }) => <p>{children}</p>}
/>
)
}And an Image component can be bound in the same way:
import { Image, types } from 'react-bricks/frontend'
interface ProductHeroImageProps {
coverImage: types.IImageSource
}
const ProductHeroImage: types.Brick<ProductHeroImageProps> = ({
coverImage,
}) => {
return (
<Image
source={coverImage}
alt="Product image"
customFieldName="coverImage"
aspectRatio={1.91}
maxWidth={1200}
/>
)
}This creates a two-way binding between the visual component and the custom field configured on the page type.
So editors can manage page-level structured values, while still editing some of them visually in the content.
A note about headlessView
If a page type does not use frontend visual editing, but only structured data in custom fields, you can set:
headlessView: trueon the page type.
In that case, the custom field controls are not shown in the sidebar.
Instead, they are shown directly in the page, more like a traditional headless CMS editing experience.
This is useful for page types that are mostly data-driven rather than visually composed with bricks.