Builder Guide
Use the Slice Library to combine modules
Arrange reusable parts from multiple modules into one tailored page without changing the platform data model.
Combine registered pieces from Contacts, Calendar, Work Orders and other features to build a page around the way your organization works. One screen can show a customer list and details alongside the customer's linked events, jobs, appointments and files.
The result is a custom workspace page assembled from existing platform modules. It does not create a new SQL table, change a platform database, or copy one module's records into another module.
What the Slice Library contains
A slice is a reusable page component: it might be an entire module workspace or a placeable piece such as its header, list, detail, form or pager. Each module has its own component key and supported parts. A part is available only when it is registered for that module and installed in the app's current component version.
In the app, builders choose registered components from the Puck Component Library. The platform also keeps a source-controlled Slice Library with component keys, part and variant definitions, examples, screenshots and versioned source snapshots. That second copy preserves the implementation and supports future catalog work; it is not a tenant database or a separate tenant-facing editor.
Use only the blocks and parts present in your app's current Puck catalog. Saving a page document cannot create an unregistered control, a new module API or a database object.
Workspace and part
Add a module once without a part property to create its workspace. The workspace owns that module's loaded data, selected record, forms, actions and refresh behavior. To rearrange its screen, place the same module block inside the workspace again with a supported part, such as list or detail. Those parts display the workspace's state; they do not create another copy of the data or permissions.
If you place no parts, the workspace uses its built-in layout. The available pieces differ by module. See Build pages from feature parts for the current per-module list and placement rules.
Build a page from multiple modules
- Open Design and choose an existing page or create a page for the intended workflow.
- Add the module workspace that will drive the page. For a customer workspace, start with
module.contacts. - Place that workspace's header, filters, list, detail, notices and pager where they fit. Use a responsive
core.containergrid to put the contact list beside its detail on desktop and stack them on smaller screens. - Add other module workspaces as siblings. To make one follow the selected contact, give Contacts a
contextKeyand set the follower'srecordFromto that exact key. - Set clear block titles and empty-state text. Save the draft, validate it, resolve every error and warning, then publish the validated version.
- Test the published page as signed-in users with different DataRoles and locations. Confirm both allowed and denied records and actions.
Example: customers and their calendar events
The Contacts workspace below publishes the selected customer under customer. Calendar follows that selection and shows only events linked to that contact. Paste the JSON into advanced JSON mode as a starting point, or place the same registered blocks in Puck.
{
"blocks": [
{
"_id": "customers",
"_type": "module.contacts",
"props": { "title": "Customers", "singular": "customer", "contextKey": "customer", "pageSize": 10 },
"children": [
{ "_id": "customers-header", "_type": "module.contacts", "props": { "part": "header" }, "children": [] },
{
"_id": "customers-grid",
"_type": "core.container",
"props": { "layout": "grid", "gridMode": "twelve-column" },
"children": [
{
"_id": "customers-list",
"_type": "module.contacts",
"props": { "part": "list", "responsive": { "desktop": { "span": 4 }, "tablet": { "span": 12 }, "mobile": { "span": 12 } } },
"children": []
},
{
"_id": "customers-detail",
"_type": "module.contacts",
"props": { "part": "detail", "responsive": { "desktop": { "span": 8 }, "tablet": { "span": 12 }, "mobile": { "span": 12 } } },
"children": []
}
]
},
{ "_id": "customers-pager", "_type": "module.contacts", "props": { "part": "pager" }, "children": [] }
]
},
{
"_id": "customer-events",
"_type": "module.calendar",
"props": { "title": "Customer events", "recordFrom": "customer", "contextKey": "customer-event", "followEmptyText": "Select a customer to see linked events." },
"children": []
}
]
}
Use record context carefully
contextKey names a workspace's selected-record context. If omitted, a module uses its default context key. A follower's recordFrom must match the source key exactly. Until a record is selected, the follower loads no records and can show its followEmptyText.
Current record-following workspaces are Contacts, Work Orders, Reservations, Calendar and Files. For example, a customer page can show a contact's work orders, reservations, attached files and linked calendar events. Other modules can still be placed independently on the same page, but they do not follow a selected record unless the feature explicitly supports it.
Following filters the module to records linked to the selected record. It does not grant access. The signed-in user's record, field, DataRole, location and action permissions are checked by each module's secured service. A hidden or deleted source record produces no broader result. Link types control which relationships may be made; a label or matching text field does not create a relationship.
Display related records versus creating them
A Calendar workspace with recordFrom displays events already linked to the selected contact. That property does not automatically add a "Create event" control to the Contacts detail panel. New work orders and reservations have their own supported create-in-context behavior; see the feature-parts guide.
For a custom React page or trusted integration, create a Calendar event through the secured Calendar operation and create its relationship through the secured Record Graph operation. The event needs its own explicit Personal or DataRole and location choice; the selected contact does not decide or grant that scope. Creation and linking are separate actions, so check the event and relationship state before retrying after an uncertain result. Use the current Developer API reference for exact operations and request contracts.
A page composition is presentation configuration. It does not bypass a module's API, action permission, record scope, or relationship rules.
A custom page is not a new data module
Changing a page's title, layout and module parts gives users a workspace tailored to their workflow while the underlying data stays in the platform's existing modules. If you need a new kind of business record, use a configured Dynamic Records module and its approved custom-field model. Do not treat page JSON or the Slice Library as a database designer.
When tenant-specific page forks are enabled, each organization can make its own presentation changes without changing the builder's base page. Template versions and page forks preserve their own version history; installing a presentation template does not migrate tenant database schemas.
Current limits
- The exact parts, controls and variants vary by module. A button or field is individually placeable only when its module exposes it as a registered part.
- Only the supported record-following modules listed above respond to
recordFrom; this setting is not a universal join between every feature. - Some cross-module create experiences require a custom React control or API client and are not automatically provided by the no-code module slice.
- Page composition changes presentation. Module schemas, APIs, permissions and tenant database structures remain platform-owned.
Capability review: 2026-11-09. See current features and setup requirements, the generated API Map and first-class module inventory.