Skip to main content

Details

From the index, merchants need to edit and view individual resources. For React Router-based Shopify apps, a resource type's details route file will use the pattern app.[resource].$id.jsx. For example, app.product.$id.jsx for managing a single product through your app.

The details template provides an efficient dual-column layout that puts editable content front and center while keeping supporting information visible in the sidebar. Use the primary column for information that defines the resource. Use the secondary column for supporting information such as status, metadata, and summaries. Provide breadcrumb navigation so merchants can return to the previous page without using the browser back button.

The details pattern follows proven design guidelines that help your app feel native to the Shopify admin. See Built for Shopify requirements for more details on these guidelines.


Anchor to Present a product details view with editable fields and sidebarPresent a product details view with editable fields and sidebar

Merchants need to edit and view a single resource with supporting info in the sidebar. This example presents a product details view for a Product Quality Auditor app with editable quality score fields in the main column and image and score in the sidebar.

Preview

<form>
<s-page heading="Mountain view">
<s-link slot="breadcrumb-actions" href="/app/puzzles">
Puzzles
</s-link>
<s-button slot="secondary-actions">Duplicate</s-button>
<s-button slot="secondary-actions" tone="critical">Delete</s-button>
{/* === */}
{/* Puzzle information */}
{/* === */}
<s-section heading="Puzzle information">
<s-grid gap="base">
<s-text-field
label="Puzzle name"
name="name"
labelAccessibilityVisibility="visible"
placeholder="Enter puzzle name"
value="Mountain view"
details="Players will see this name when browsing puzzles."
/>
<s-text-area
label="Description"
name="description"
labelAccessibilityVisibility="visible"
placeholder="Brief description of your puzzle"
value="A beautiful mountain landscape puzzle"
details="Help players understand what your puzzle features"
/>
<s-money-field
label="Price"
name="price"
labelAccessibilityVisibility="visible"
placeholder="0.00"
value="9.99"
details="Set the price for this puzzle"
/>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.shopify.com/shopifycloud/polaris.js"></script>
<title>Pattern</title>
</head>
<body>
<!-- === -->
<!-- Details page pattern -->
<!-- === -->
<form>
<s-page heading="Mountain view">
<s-link slot="breadcrumb-actions" href="/app/puzzles">Puzzles</s-link>
<s-button slot="secondary-actions">Duplicate</s-button>
<s-button slot="secondary-actions" tone="critical">Delete</s-button>
<!-- === -->
<!-- Puzzle information -->
<!-- === -->
<s-section heading="Puzzle information">
<s-grid gap="base">
<s-text-field
label="Puzzle name"
name="name"
labelAccessibilityVisibility="visible"
placeholder="Enter puzzle name"
value="Mountain view"
details="Players will see this name when browsing puzzles."
></s-text-field>
<s-text-area
label="Description"
name="description"
labelAccessibilityVisibility="visible"
placeholder="Brief description of your puzzle"
value="A beautiful mountain landscape puzzle"

Anchor to Confirm destructive actions with Modal APIConfirm destructive actions with Modal API

Use the Modal API to confirm destructive actions like deleting a resource. The modal prevents accidental data loss by requiring explicit confirmation.

Preview

<s-grid justifyItems="center" alignItems="center" minBlockSize="200px">
<s-button
tone="critical"
commandFor="delete-modal"
command="--show"
>
Delete
</s-button>

<s-modal id="delete-modal" heading="Delete product?">
<s-stack direction="block" gap="base">
<s-text>
Are you sure you want to delete this product? This action cannot be undone.
</s-text>
<s-banner tone="warning">
<s-text>
This will permanently remove the product and all associated data.
</s-text>
</s-banner>
</s-stack>
<s-button
slot="primary-action"
variant="primary"
tone="critical"
onClick={() => {
console.log("Product deleted");
}}
>
Delete
</s-button>
<s-button
slot="secondary-actions"
commandFor="delete-modal"
command="--hide"
>
Cancel
</s-button>
</s-modal>
</s-grid>
<s-grid justifyItems="center" alignItems="center" minBlockSize="200px">
<s-button
tone="critical"
commandFor="delete-modal"
command="--show"
>
Delete
</s-button>

<s-modal id="delete-modal" heading="Delete product?">
<s-stack direction="block" gap="base">
<s-text>
Are you sure you want to delete this product? This action cannot be undone.
</s-text>
<s-banner tone="warning">
<s-text>
This will permanently remove the product and all associated data.
</s-text>
</s-banner>
</s-stack>
<s-button
slot="primary-action"
variant="primary"
tone="critical"
>
Delete
</s-button>
<s-button
slot="secondary-actions"
commandFor="delete-modal"
command="--hide"
>
Cancel
</s-button>
</s-modal>
</s-grid>

Anchor to Retain unsaved changes with Save BarRetain unsaved changes with Save Bar

Add data-save-bar to your form element to enable the Save Bar API, which displays save/discard controls when the form has unsaved changes.

<form
data-save-bar
onSubmit={(event) => {
event.preventDefault();
const formData = new FormData(event.target);
const formEntries = Object.fromEntries(formData);
console.log("Form submitted", formEntries);
}}
onReset={(event) => {
console.log("Changes discarded");
}}
>
<s-section heading="Basic information">
<s-box border="base" borderRadius="base" padding="base">
<s-stack direction="block" gap="base">
<s-text-field
label="Title"
name="title"
value="Premium Cotton T-Shirt"
details="Minimum 10 characters recommended"
/>
<s-text-area
label="Description"
name="description"
value="Our premium cotton t-shirt is made from 100% organic cotton."
rows={4}
/>
</s-stack>
</s-box>
</s-section>
</form>
<!-- Save Bar integration - wrap forms with data-save-bar attribute -->
<form data-save-bar>
<s-section heading="Basic information">
<s-box border="base" borderRadius="base" padding="base">
<s-stack direction="block" gap="base">
<s-text-field
label="Title"
name="title"
value="Premium Cotton T-Shirt"
details="Minimum 10 characters recommended"
></s-text-field>
<s-text-area
label="Description"
name="description"
value="Our premium cotton t-shirt is made from 100% organic cotton."
rows="4"
></s-text-area>
</s-stack>
</s-box>
</s-section>
</form>

Was this page helpful?