← Back to all how-tos

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.

Estimated time: 6 minRaw Markdown

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:

  • heading
  • content
  • footer

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 heading slot is for the page hero area
  • the content slot is for the main product content
  • the footer slot 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 slot
  • label: the label shown in the editing interface
  • min: the minimum number of bricks required in that slot
  • max: the maximum number of bricks allowed in that slot
  • allowedBlockTypes: the bricks allowed in that slot
  • editable: whether editors can change the slot content
  • getDefaultContent: 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: 1
  • max: 1
  • allowedBlockTypes: ['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 features brick
  • one testimonial-single brick populated with the black-blurred-divider story

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:

  • heading is editable
  • content is editable
  • footer is not editable
editable: true

For the footer slot, we use:

editable: false

This 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