Record Edit Modes
Choose between modal and full-page record forms with the editMode metadata flag.
Record Edit Modes
ObjectUI's default console shell (@object-ui/app-shell) supports two ways
to render the create/edit form for a record:
- Modal (default) — the form opens in an overlay dialog above the current view. Best for short forms, quick edits, and contextual data entry.
- Page — the form takes over a full route. Best for long forms, multi-tab or wizard layouts, or anywhere you need a deep-linkable URL that survives a refresh and integrates with the browser back button.
Both modes use the same <ObjectForm> pipeline under the hood, so all
field types, sections, validations, and visibility expressions work
identically in either mode.
Choosing a mode
Set editMode on the object metadata:
// metadata/objects/account.json
{
"name": "account",
"label": "Account",
"editMode": "page", // "modal" (default) | "page"
"fields": {
"name": { "type": "text", "label": "Name", "required": true },
"industry": { "type": "picklist", "label": "Industry" },
"owner": { "type": "lookup", "label": "Owner", "reference_to": "user" }
}
}Omitting editMode (or setting it to "modal") keeps the existing
behavior — clicking Create or Edit opens the global ModalForm
overlay.
URL patterns
When editMode: "page" is set, the console renders the form on a
dedicated route under the active app:
| Action | URL |
|---|---|
| Create | /apps/:appName/:objectName/new |
| Edit | /apps/:appName/:objectName/record/:recordId/edit |
Examples (for an app sales and an object account):
- Create:
https://your-console.example/apps/sales/account/new - Edit:
https://your-console.example/apps/sales/account/record/0015e000abcd/edit
These URLs are stable. Users can bookmark them, share them in chat, or
refresh the page mid-edit (the form rehydrates from the URL :recordId).
Triggering the routes from JSON
In addition to the implicit "click create/edit on a list" entry point,
two declarative actions let you open the page-mode routes from any
<action:button> in metadata:
{
"type": "action:button",
"label": "New Account",
"icon": "plus",
"action": {
"action": "navigate_create",
"params": { "objectName": "account" }
}
}{
"type": "action:button",
"label": "Edit",
"icon": "pencil",
"action": {
"action": "navigate_edit",
"params": {
"objectName": "account",
"recordId": "${record.id}"
}
}
}When invoked from inside an ObjectView, the action context already
carries the active objectName, so objectName may be omitted from the
params:
{
"type": "action:button",
"label": "New",
"action": { "action": "navigate_create" }
}Behavior summary
| Aspect | Modal | Page |
|---|---|---|
| Default | ✅ | — |
| Deep-linkable URL | ❌ | ✅ |
| Survives refresh | ❌ | ✅ |
| Back button closes form | n/a | ✅ |
| Best for | quick edits | long / multi-section forms |
Migrating an existing object
The change is additive — existing apps continue to work unchanged. To migrate a single object to page mode:
- Add
"editMode": "page"to the object metadata. - (Optional) Adjust the form layout — page mode pairs well with
formType: "tabbed"orformType: "wizard"for long forms. - Reload the console. Existing Create / Edit entry points automatically route to the new pages; no UI code changes required.