Who this is for. Content modellers and developers deciding how to model a new kind of content. After this page you can say whether it should be a page, a custom entity with URLs of its own, or a custom entity that only feeds other pages.

What a custom entity is

A custom entity is a content type defined at runtime, with no framework code. Its definition, created in the admin under Customization, names the type: an identifier, a layout, the relationship definitions that link it to other types, and a set of switches. Its records are the entries authors make. Creating a definition also creates its layout, an element in the admin menu and a privilege target, so the new type appears in the admin with permissions of its own.

This is how a site builder delivers a whole application, such as a store locator, a directory or a course catalogue, with templates and admin configuration only. The last page of this unit builds a learning site that way.

A record behaves like a page in the ways that matter to a template. It has a layout and layout areas, and its content lives in revisions: every edit makes a new revision, and visitors see the active one. Revisions cannot be switched off for a definition. Publishing can: when a definition is not publishable, every record is visible.

The test

If the thing has its own fields, its own listing, and does not belong in the site's page tree, it is a custom entity. As three questions:

  1. Does every one of them carry the same fields? Stores have an address, opening hours and a map pin; campaign landing pages have little in common but a title.
  2. Is there a list of them, on a page of its own or inside other pages?
  3. Would they sit awkwardly in the page tree? Hundreds of entries under one parent page, or entries with no place in the navigation at all, are a sign they are not pages.

Three yes answers make a custom entity; a no to the first makes a page. When one of the built-in types (pages, blog posts, books, FAQ) already fits, it comes first: Which type, or none compares them.

A record compared with a page

PageCustom entity record
Where it livesIn the page tree, under a parent pageUnder its definition; its URL starts with the definition's record path
LayoutChosen per page, on each revisionOne layout for the whole definition: every record renders through the same template
ListingChild pages, read by a templateA listing route from the definition's path, with paging and tag and category filters
RevisionsAlwaysAlways
PublishingAlwaysOptional, per definition
Approval workflowsAvailableNot available
Links to other contentRecord and records layout areasRelationship definitions to other records, and record layout areas
NestingParent and child pagesRecords of one type nesting among themselves, or typed parent and child definitions

Three cases

A store locator: a custom entity

Every store has an address, opening hours and a map pin. Visitors browse a paged list of stores and open one at /store/richmond. A store has no business in the page tree beside About and Contact. All three answers are yes: a store definition with a path and a record path gives the list, the detail pages and their URLs. Listing and detail templates builds it.

Testimonials shown by a component: a custom entity without URLs

A testimonial has a quote, a name and a photo, and a component shows three of them on the home page and on product pages. The fields repeat and there is a list, but no testimonial needs a page of its own. Make a testimonial definition and leave its path and its record path empty: neither a listing route nor a detail route exists, and the component reads the records with the query helper (Querying records from a template).

A one-off campaign landing page: a page

A landing page for one campaign has a hero, a few sections and a form, chosen for that campaign alone. Nothing about it repeats, it belongs in the page tree and the navigation, and its author expects to pick its layout. It is a page. As a custom entity it would be a definition with one record and a layout no other record uses.