Page Types, Templates and Custom Fields
Create a page template
Define a page template with fixed slots to give a page type a structured layout.
In this how-to, you'll learn how to create a page template for a page type in React Bricks.
Page templates let you define a fixed page structure made of slots.
Each slot is a specific area of the page with its own rules, such as:
- which bricks are allowed
- how many bricks can be added
- whether the slot is editable
- which default content should appear when a new page is created
This is especially useful for pages that need a predictable structure, such as product pages in an ecommerce.
For a real-world example, you can also see the React Bricks Next.js Commerce demo: Next.js Commerce with React Bricks
Why templates are useful
Templates are useful when a page type should not be a completely free list of bricks.
For example, a product page may need:
- a fixed heading area
- a fixed product summary or add-to-cart section that editors should not remove
- a flexible content section
- a predefined area for related content or a call to action
Instead of letting editors add any brick anywhere, a template lets you define these areas explicitly.
This gives editors flexibility where needed, while keeping the overall page structure consistent.
Start from a page type
In the previous guide, we created simple page types using the pageTypes array.
Now we'll add a template property to a product page type:
const pageTypes: types.IPageType[] = [
{
name: 'product',
pluralName: 'products',
defaultStatus: types.PageStatus.Published,
template: [
{
slotName: 'heading',
label: 'Heading',
min: 1,
max: 1,
allowedBlockTypes: ['hero-unit'],
editable: true,
},
{
slotName: 'content',
label: 'Content',
min: 0,
max: 4,
allowedBlockTypes: [
'text-image',
'features',
'call-to-action',
'testimonial-single',
],
editable: true,
getDefaultContent: () => [
'features',
{
brickName: 'testimonial-single',
storyName: 'black-blurred-divider',
},
],
},
{
slotName: 'footer',
label: 'Footer',
min: 1,
max: 1,
allowedBlockTypes: ['newsletter-subscribe'],
editable: false,
},
],
},
]This template defines 3 slots:
headingcontentfooter
What a template slot is
Each object inside the template array is a slot definition.
A slot is a fixed part of the page with its own rules.
In this example:
- the
headingslot is for the page hero area - the
contentslot is for the main product content - the
footerslot is for a fixed newsletter area
Explain the slot properties
Here are the most important properties used in this example:
slotName: the unique internal name of the slotlabel: the label shown in the editing interfacemin: the minimum number of bricks required in that slotmax: the maximum number of bricks allowed in that slotallowedBlockTypes: the bricks allowed in that sloteditable: whether editors can change the slot contentgetDefaultContent: the default content created for the slot
The heading slot
Let's look at the first slot:
{
slotName: 'heading',
label: 'Heading',
min: 1,
max: 1,
allowedBlockTypes: ['hero-unit'],
editable: true,
},This means:
- the slot is called
heading - editors see it labeled as
Heading - it must always contain exactly 1 brick
- that brick must be
hero-unit - the slot is editable
Because min and max are both 1, the slot always contains exactly one block that can't be removed.
The content slot
Now look at the second slot:
{
slotName: 'content',
label: 'Content',
min: 0,
max: 4,
allowedBlockTypes: [
'text-image',
'features',
'call-to-action',
'testimonial-single',
],
editable: true,
getDefaultContent: () => [
'features',
{
brickName: 'testimonial-single',
storyName: 'black-blurred-divider',
},
],
},This slot is more flexible:
- it can contain from 0 to 4 blocks
- editors can choose among several allowed bricks
- it starts with default content
So this slot behaves like a controlled but flexible content area.
The footer slot
Now let's look at the last slot:
{
slotName: 'footer',
label: 'Footer',
min: 1,
max: 1,
allowedBlockTypes: ['newsletter-subscribe'],
editable: false,
},This means:
- the slot must always contain exactly 1 block
- that block must be
newsletter-subscribe - editors cannot change the slot content
This is useful when a section should always be present and should not be removed or replaced by editors.
Why there is no getDefaultContent here
The footer slot does not define getDefaultContent.
That is fine in this case, because the slot already requires exactly one block:
min: 1max: 1allowedBlockTypes: ['newsletter-subscribe']
So the slot will contain one newsletter-subscribe block using that brick's default content.
How getDefaultContent works in templates
getDefaultContent returns the initial blocks that will be added to that slot when a new page is created.
In this example:
getDefaultContent: () => [
'features',
{
brickName: 'testimonial-single',
storyName: 'black-blurred-divider',
},
]we use 2 kinds of default content:
- a string like
'features', which means “add this brick using its default props” - a story object, which means “add this brick using a specific story”
So this slot starts with:
- one
featuresbrick - one
testimonial-singlebrick populated with theblack-blurred-dividerstory
This is a nice way to give editors a good starting point while keeping the structure consistent.
Why editable matters
Each slot can also control whether editors are allowed to change it.
In this example:
headingis editablecontentis editablefooteris not editable
editable: trueFor the footer slot, we use:
editable: falseThis is useful for sections that should stay fixed, especially for system-controlled or mandatory parts of the page.
What's next
Templates let you define the structure of a page type.
The next step is often adding custom fields, so editors can manage page-specific data alongside the visual content.
Docs reference: Page Templates