Saleor Dashboard Detail Pages
Conventions for DetailPageLayout entity views under src/<feature>/.
Start here for broader refresh: saleor-dashboard-entity-detail — page anatomy, Detail* vs Settings*, refactor checklist (e.g. collections).
Foldable sections
For expandable sections (advanced settings, rate rows, postal ranges, etc.) use DetailGroupBox with Title2 — documented in saleor-dashboard-styles. Do not introduce new UI with the legacy @dashboard/components/Accordion.
Section nav layout
Long detail pages with DetailSectionNav (4+ scroll sections) use DetailPageSectionLayout — nav rail at 25% width (min 10rem) + main column with gap={4}. Do not nest DetailPageContent inside (that component is for single-column pages only). See saleor-dashboard-entity-detail for the full table and example.
Settings sections (DetailSettingsCard)
On entity detail pages, group fields in DetailSettingsCard (not DashboardCard or nested cards). Full language:
- Primary vs secondary sidebar card headers (Inventory / Delivery pattern)
introrow for leading description (Payment gateways pattern)- Card vs open section — when to skip the border
- Channel availability tiers, foldables, SEO
unwrapped - SEO last in the main column by default (identity → primary content → SEO)
- Fixed-at-creation fields —
FixedAtCreationField(disabled Input + lock + “Fixed at creation. …” helper), never a disabled Combobox - Vercel design restraint rules (earn a surface, no nesting)
→ saleor-dashboard-entity-detail
Metadata in Header Modal
Edit views — metadata lives in a header modal, not the main form.
| Layer | Responsibility |
|---|---|
*MetadataDialog |
MetadataDialog + useMetadataForm + useHandleMetadataSubmit |
View (*Details.tsx) |
URL dialog state via createDialogActionHandlers, renders dialog |
*DetailsPage |
TopNav.MetadataButton → onShowMetadata |
| Form | No metadata fields on update; create flows may keep inline <Metadata> |
Reference implementations
src/products/components/ProductMetadataDialog/src/customers/components/CustomerMetadataDialog/src/warehouses/components/WarehouseMetadataDialog/src/modeling/components/PageMetadataDialog/
Checklist (edit view)
- Add
"view-metadata"to the entity URL dialog union (urls.ts). - Create
<Entity>MetadataDialogusingPageDetailsDocument(or entity query doc) asrefetchDocument. - View:
openModal("view-metadata")/closeModal; removecreateMetadataUpdateHandler. - Page:
TopNav.MetadataButtonwithdata-test-id="show-<entity>-metadata". - Remove inline
<Metadata>from page content; skip metadata in update submit data. - Create views keep inline
<Metadata>+createMetadataCreateHandler(no entity id yet).
URL dialog wiring
const [openModal, closeModal] = createDialogActionHandlers(
navigate,
params => entityUrl(id, params),
params,
);
<EntityMetadataDialog
open={params.action === "view-metadata" && !!entity}
entity={entity}
/>;
MetadataDialog component
Shared UI: src/components/MetadataDialog/. Entity dialogs are thin wrappers — copy an existing one and swap the GraphQL document + title message.
TopNav Actions
TopNav.MetadataButton— metadata (edit views only)TranslationsButton— whenMANAGE_TRANSLATIONSTopNav.Menu— extensions → entity actions → related settings hub (if any) → GraphiQL → Delete last (see entity-detail skill)- Set
actionsGap={3}when multiple header actions
Further Reading
saleor-dashboard-entity-detail— update language for daily entity detailsrules/metadata-modal.md— step-by-step migration from inline metadatasaleor-dashboard-stylesskill — layout and Macaw UI patterns