Skip to main content

Pages

Pages are a built-in form structure that divides a form into multiple navigable sheets. Unlike field types such as section, pages are a first-class form primitive — they live at the top level of every form definition rather than inside the field tree.

Every form definition has a pages array. A form with a single page behaves identically to a traditional single-scroll form. A multi-page renderer can show page-title tabs at the top, Previous / Next controls at the bottom, or both.

Page Entry Properties

Each entry in the pages array has the following shape:

PropertyTypeRequiredDescription
idstringYesUnique identifier for this page
titlestringNoDisplay label for the page (defaults to "Sheet N" in the builder)
autoAdvancebooleanNoReserved — automatically advance to the next page when all fields are answered. Not yet active in the renderer.
fieldsFieldDefinition[]NoThe fields rendered on this page. May include section fields to group questions.

Answer Format

Pages store no answers. All answers live on individual fields within each page's fields array.

Schema Example

Single-page form

A form with one page behaves exactly like a classic single-scroll form — no navigation UI is shown.

id: intake-form
title: Patient Intake
pages:
- id: page_1
title: Demographics
fields:
- id: first_name
fieldType: text
question: First Name
required: true
- id: dob
fieldType: text
question: Date of Birth
inputType: date

Multi-page form

A form with two or more pages can show top page tabs and/or a navigation bar (← Previous · X / Y · Next →) at the bottom of the renderer.

id: intake-form
title: Patient Intake
pages:
- id: page_1
title: Demographics
fields:
- id: first_name
fieldType: text
question: First Name
required: true
- id: page_2
title: Medical History
fields:
- id: allergies
fieldType: longtext
question: List any known allergies

Renderer Behavior

Implemented in RendererBody and PageNavigator.

Configure navigation on the renderer component:

<EsheetRenderer
formDataInput={formDefinition}
topNavigation={true}
bottomNavigation={false}
validateNavigation={true}
/>
PropDefaultBehavior
topNavigationfalseShows page-title tabs above the active page.
bottomNavigationtrueShows Previous / page count / Next controls below the active page.
validateNavigationtrueBlocks forward movement from either navigation surface when required fields on the current page are unanswered.

Navigation validation is separate from submit validation. Turning validateNavigation off allows page changes but does not allow an invalid form to submit or change the behavior of getValidResponse().

ConditionBehavior
pages.length === 1Fields render directly, no navigation UI shown
pages.length > 1PageNavigator renders the enabled top tabs and/or bottom bar
First page"Previous" button is disabled
Last page"Next →" button is replaced with "Last page" text

Visibility rules (rules) on individual fields are evaluated per page — hidden fields are excluded from the rendered output on that page.

Builder Behavior

The Canvas panel header displays a Sheets bar when pages are present.

  • Tabs: each page appears as a labeled tab. Clicking switches the active page.
  • Add: click + Sheet to append a new blank page.
  • Delete: click Delete sheet to remove the active page. Disabled when only one page remains (minimum 1 page enforced).
  • Reorder: drag a tab left or right to change page order.
  • Rename: double-click a tab, or click the ✎ pencil icon on the active tab, to edit the page title inline.

Form Store API

These methods on FormStore manage pages programmatically:

// Add a new blank page (optionally with a title and insertion index)
form.getState().addPage({ title?: string; index?: number }): string

// Remove a page and all its fields. Returns false if only 1 page remains.
form.getState().removePage(pageId: string): boolean

// Move a page to a new index.
form.getState().movePage(pageId: string, toIndex: number): boolean

// Update a page's display title.
form.getState().updatePageTitle(pageId: string, title: string): boolean

// Set the auto-advance flag for a page (reserved; not yet active in renderer).
form.getState().setPageAutoAdvance(pageId: string, autoAdvance: boolean): boolean

Constraints

  • Minimum 1 page: removePage returns false and is a no-op when the form has only one page.
  • No nesting: pages cannot be placed inside section fields or inside other pages. Pages exist exclusively at the form root level.
  • No field-level pages: pages are not a fieldType — they cannot be added through the fields API (addField) and do not appear in the field toolbox.