← Back to all how-tos

Page Types, Templates and Custom Fields

Create a page type

Organize content into different kinds of pages by defining page types in the React Bricks configuration.

Estimated time: 5 minRaw Markdown

In this how-to, you'll learn how to create simple page types in React Bricks.

In this first guide, we'll focus on simple page types without templates, custom fields or external data integration. These are other powerful features of page types, and we'll cover them in the next guides.

Why page types are useful

Page types are a way to group similar pages and apply specific configuration to them.

This is important because not every page in a project has the same purpose.

For example:

  • marketing pages may use most bricks
  • blog pages may need a smaller, dedicated set of blog bricks
  • a layout fragment like a header is not really a normal routed page
  • some page types may need a slug prefix
  • some page types may need different defaults when a new page is created
  • some pages may need to have a fixed template-based structure
  • some pages may need custom fields or fetch data from external data sources

Using page types helps editors create the right kind of content with the right structure, defaults and available bricks.

Where page types are defined

In the React Bricks configuration, pageTypes is an array of types.IPageType objects.

For starter projects, you'll usually find them in a pageTypes.ts file inside the React Bricks configuration folder.

The docs reference is here: Page Types

A simple generic page type

Let's start with a generic page page type.

In this example, editors can use almost all bricks, except the ones reserved for the blog:

const pageTypes: types.IPageType[] = [
  {
    name: 'page',
    pluralName: 'pages',
    defaultLocked: false,
    defaultStatus: types.PageStatus.Published,
    getDefaultContent: () => [],
    excludedBlockTypes: ['blog-title', 'blog-text', 'blog-image'],
  },
]

Here is what these properties mean:

  • name: the internal name of the page type
  • pluralName: the plural label shown in the editing interface
  • defaultLocked: whether new pages of this type start locked or unlocked
  • defaultStatus: the initial page status for new pages
  • getDefaultContent: the default content created when a new page of this type is added
  • excludedBlockTypes: the bricks editors are not allowed to use for this page type

This is a good approach when most bricks are allowed and you only want to exclude a few special-purpose ones.

A blog page type with slugPrefix

Now let's look at a blog page type:

{
  name: 'blog',
  pluralName: 'Blog',
  defaultLocked: false,
  defaultStatus: types.PageStatus.Published,
  getDefaultContent: () => [],
  slugPrefix: { default: 'blog/post/' },
  allowedBlockTypes: ['blog-title', 'blog-text', 'blog-image', 'blog-code'],
},

This example introduces 2 important ideas.

allowedBlockTypes

allowedBlockTypes defines exactly which bricks can be used in this page type.

So here, blog pages can use only:

  • blog-title
  • blog-text
  • blog-image
  • blog-code

This is useful when you want a stricter content model for a specific kind of page.

slugPrefix

slugPrefix automatically prepends a prefix to the page slug.

In this case:

slugPrefix: { default: 'blog/post/' }

means blog pages will automatically have blog/post/ before the rest of the slug.

So if the editor creates a page with slug my-first-post, the final slug becomes:

blog/post/my-first-post

This helps enforce a consistent URL structure for a specific content type.

It can also define different prefixes for different languages, so localized projects can enforce a different slug structure for each locale.

A layout page type with isEntity

Now let's look at a page type for layout fragments like header and footer:

{
  name: 'layout',
  pluralName: 'layout',
  defaultLocked: false,
  defaultStatus: types.PageStatus.Published,
  getDefaultContent: () => [],
  isEntity: true,
  allowedBlockTypes: ['header', 'footer'],
},

This example is interesting for 2 reasons.

allowedBlockTypes

Again, we restrict the available bricks, this time to:

  • header
  • footer

That prevents editors from using unrelated content bricks in a layout entity.

isEntity

The isEntity flag changes how this page type is organized in the editor.

When:

isEntity: true

pages of this type do not appear in the normal left sidebar together with standard pages.

Instead, they appear under the Entities tab.

This is usually used for content that is not a normal routed page, such as:

  • headers
  • footers
  • reusable fragments
  • site-wide shared pieces of content

So isEntity is a useful way to keep special content separate from normal pages.

allowedBlockTypes vs excludedBlockTypes

Both properties control which bricks editors can use, but they serve slightly different needs.

Use:

  • excludedBlockTypes when most bricks are allowed and you only want to remove a few
  • allowedBlockTypes when you want to strictly limit the available bricks

If a brick is included in both allowedBlockTypes and excludedBlockTypes, it is considered excluded.

So:

  • the generic page example uses excludedBlockTypes
  • the blog and layout examples use allowedBlockTypes

Final example

Here is what a small pageTypes array could look like:

const pageTypes: types.IPageType[] = [
  {
    name: 'page',
    pluralName: 'pages',
    defaultLocked: false,
    defaultStatus: types.PageStatus.Published,
    getDefaultContent: () => [],
    excludedBlockTypes: ['blog-title', 'blog-text', 'blog-image'],
  },
  {
    name: 'blog',
    pluralName: 'Blog',
    defaultLocked: false,
    defaultStatus: types.PageStatus.Published,
    getDefaultContent: () => [],
    slugPrefix: { default: 'blog/post/' },
    allowedBlockTypes: ['blog-title', 'blog-text', 'blog-image', 'blog-code'],
  },
  {
    name: 'layout',
    pluralName: 'layout',
    defaultLocked: false,
    defaultStatus: types.PageStatus.Published,
    getDefaultContent: () => [],
    isEntity: true,
    allowedBlockTypes: ['header', 'footer'],
  },
]

What's next

Page types can do even more than this.

They can also define templates to create structured page layouts with fixed slots and controlled editing areas, and they can add custom fields for page-specific data.

We'll cover templates and custom fields in the next guides.