Homepage
The first thing merchants see when they open your app in App Home is a landing page, associated with the route file app._index.jsx in React Router-based Shopify apps.
It provides a clear entry point for merchants, and an opportunity to provide daily value through status updates, metrics, and clear actions merchants can take. Surface key information at a glance like performance metrics, items needing attention, and onboarding guidance for new users.
Build each card on the page as a section, and put anything that describes or acts on a whole card in its header rather than its body. Name each section with heading, and add supporting text with subheading. Use the supplemental slot for the card's status, such as setup progress, and the secondary-actions slot for its actions, such as a link to see more or a dismiss button. A section without a visible heading, such as a row of metrics, still needs an accessibilityLabel.
Put lists such as setup steps and news straight into the section, with a divider between rows instead of a box around each one. Keep bordered tiles for items that stand on their own in a grid, such as templates and apps.
The homepage pattern provides this foundation while following proven design guidelines that help your app feel native to the Shopify admin. See Built for Shopify requirements for more details on these guidelines for apps.
Supported components
Available APIs
Recommended compositions
Supported components
Available APIs
Recommended compositions
Anchor to Use casesUse cases
- Providing a dashboard with key metrics and status updates
- Surfacing items that need merchant attention
- Guiding new users through onboarding steps
Anchor to ExamplesExamples
Merchants need a clear entry point with key information and actions. This example surfaces a homepage for a puzzle app with an upgrade banner, a setup guide, metrics, a callout card, puzzle templates, news, and featured apps.
The setup guide reports its progress in the supplemental slot, and the setup guide, callout card, and featured apps sections each put an icon-only dismiss button in their secondary-actions slot, named by its accessibilityLabel.
The templates and news sections link to their full lists from the same slot, and the metrics section, which has no visible heading, is named by its accessibilityLabel. Setup steps and news items are rows separated by dividers, and templates and featured apps are individual tiles in a responsive grid. Each app tile is one clickable, so it holds no button of its own.
Preview
jsx
// @framework-globals: useState
const steps = [
{
id: 'upload-image',
label: 'Upload an image for your puzzle',
description:
'Start by uploading a high-quality image that will be used to create your puzzle. For best results, use images that are at least 1200x1200 pixels.',
primaryAction: 'Upload image',
secondaryAction: 'Image requirements',
},
{
id: 'choose-template',
label: 'Choose a puzzle template',
description:
'Select a template for your puzzle - choose between 9-piece (beginner), 16-piece (intermediate), or 25-piece (advanced) layouts.',
primaryAction: 'Choose template',
secondaryAction: 'See all templates',
},
{
id: 'customize-pieces',
label: 'Customize puzzle piece shapes',
description:
'Make your puzzle unique by customizing the shapes of individual pieces. Choose from classic, curved, or themed piece styles.',
primaryAction: 'Customize pieces',
secondaryAction: 'Learn about piece styles',
},
];
const templates = [
{id: '4-piece', name: '4-Pieces', image: 'https://cdn.shopify.com/static/images/polaris/patterns/4-pieces.png'},
{id: '9-piece', name: '9-Pieces', image: 'https://cdn.shopify.com/static/images/polaris/patterns/9-pieces.png'},
{id: '16-piece', name: '16-Pieces', image: 'https://cdn.shopify.com/static/images/polaris/patterns/16-pieces.png'},
];
const news = [
{
id: 'new-shapes-and-themes',
date: 'Jan 21, 2025',
title: 'New puzzle shapes and themes added',
summary:
"We've added 5 new puzzle piece shapes and 3 seasonal themes to help you create more engaging and unique puzzles for your customers.",
},
{
id: 'puzzle-difficulty-customization',
date: 'Nov 6, 2024',
title: 'Puzzle difficulty customization features',
summary:
'Now you can fine-tune the difficulty of your puzzles with new rotation controls, edge highlighting options, and piece recognition settings.',
},
];
const apps = [
{
name: 'Shopify Flow',
href: 'https://apps.shopify.com/flow',
icon: 'https://cdn.shopify.com/app-store/listing_images/15100ebca4d221b650a7671125cd1444/icon/CO25r7-jh4ADEAE=.png',
description: 'Automate everything and get back to business.',
},
{
name: 'Shopify Planet',
href: 'https://apps.shopify.com/planet',
icon: 'https://cdn.shopify.com/app-store/listing_images/87176a11f3714753fdc2e1fc8bbf0415/icon/CIqiqqXsiIADEAE=.png',
description: 'Offer carbon-neutral shipping and showcase your commitment.',
},
];
const [visible, setVisible] = useState({
banner: true,
setupGuide: true,
calloutCard: true,
featuredApps: true,
});
const [expanded, setExpanded] = useState({});
const [completed, setCompleted] = useState({});
const completedCount = steps.filter((step) => completed[step.id]).length;
return (
<s-page>
<s-button slot="primary-action" variant="primary">Create puzzle</s-button>
<s-button slot="secondary-actions">Browse templates</s-button>
<s-button slot="secondary-actions">Import image</s-button>
{/* === */}
{/* Banner */}
{/* Use banners sparingly. Only one banner should be visible at a time. */}
{/* If dismissed, use local storage or a database entry to avoid showing this section again to the same user. */}
{/* === */}
{visible.banner && (
<s-banner
dismissible
onDismiss={() => setVisible({ ...visible, banner: false })}
>
3 of 5 puzzles created.{" "}
<s-link href="#">Upgrade to Puzzlify Pro</s-link> to create unlimited
puzzles.
</s-banner>
)}
{/* === */}
{/* Setup guide */}
{/* Keep instructions brief and direct. Only ask merchants for required information. */}
{/* The header holds the guide's progress in the supplemental slot and its dismiss button in the secondary-actions slot. */}
{/* Steps sit directly in the card, separated by dividers. A step's details open beneath it, in line with its label, without a box of their own. */}
{/* If dismissed, use local storage or a database entry to avoid showing this section again to the same user. */}
{/* === */}
{visible.setupGuide && (
<s-section
heading="Setup guide"
subheading="Use this personalized guide to get your store ready for sales."
>
<s-text slot="supplemental" color="subdued">
{completedCount} of {steps.length} steps completed
</s-text>
<s-button
slot="secondary-actions"
accessibilityLabel="Dismiss guide"
onClick={() => setVisible({ ...visible, setupGuide: false })}
variant="tertiary"
tone="neutral"
icon="x"
></s-button>
<s-stack gap="small">
{steps.map((step, index) => (
<s-stack key={step.id} gap="small">
{index > 0 && <s-divider />}
<s-grid
gridTemplateColumns="1fr auto"
gap="base"
alignItems="center"
>
<s-checkbox
label={step.label}
checked={Boolean(completed[step.id])}
onInput={(e) =>
setCompleted({ ...completed, [step.id]: e.currentTarget.checked })
}
></s-checkbox>
<s-button
onClick={() =>
setExpanded({ ...expanded, [step.id]: !expanded[step.id] })
}
accessibilityLabel={`Toggle ${step.label} details`}
variant="tertiary"
icon={expanded[step.id] ? "chevron-up" : "chevron-down"}
></s-button>
</s-grid>
{expanded[step.id] && (
<s-grid
gridTemplateColumns="1fr auto"
gap="base"
alignItems="center"
paddingInlineStart="large-200"
>
<s-stack gap="small-200">
<s-paragraph color="subdued">{step.description}</s-paragraph>
<s-stack direction="inline" gap="small-200">
<s-button variant="primary">{step.primaryAction}</s-button>
<s-button variant="tertiary" tone="neutral">
{step.secondaryAction}
</s-button>
</s-stack>
</s-stack>
<s-box maxBlockSize="80px" maxInlineSize="80px">
<s-image
src="https://cdn.shopify.com/s/assets/admin/checkout/settings-customizecart-705f57c725ac05be5a34ec20c05b94298cb8afd10aac7bd9c7ad02030f48cfa0.svg"
alt=""
/>
</s-box>
</s-grid>
)}
</s-stack>
))}
{/* Add steps to the array above to add them to the guide */}
</s-stack>
</s-section>
)}
{/* === */}
{/* Metrics cards */}
{/* Your app homepage should provide merchants with quick statistics or status updates that help them understand how the app is performing for them. */}
{/* A section with no visible heading still needs a name, so give it an accessibilityLabel. */}
{/* === */}
<s-section padding="base" accessibilityLabel="Puzzle metrics">
<s-grid
gridTemplateColumns="@container (inline-size <= 400px) 1fr, 1fr auto 1fr auto 1fr"
gap="small"
>
<s-clickable
href="#"
paddingBlock="small-400"
paddingInline="small-100"
borderRadius="base"
>
<s-grid gap="small-300">
<s-heading>Total Designs</s-heading>
<s-stack direction="inline" gap="small-200">
<s-text>156</s-text>
<s-badge tone="success" icon="arrow-up">
12%
</s-badge>
</s-stack>
</s-grid>
</s-clickable>
<s-divider direction="block" />
<s-clickable
href="#"
paddingBlock="small-400"
paddingInline="small-100"
borderRadius="base"
>
<s-grid gap="small-300">
<s-heading>Units Sold</s-heading>
<s-stack direction="inline" gap="small-200">
<s-text>2,847</s-text>
<s-badge tone="warning">0%</s-badge>
</s-stack>
</s-grid>
</s-clickable>
<s-divider direction="block" />
<s-clickable
href="#"
paddingBlock="small-400"
paddingInline="small-100"
borderRadius="base"
>
<s-grid gap="small-300">
<s-heading>Return Rate</s-heading>
<s-stack direction="inline" gap="small-200">
<s-text>3.2%</s-text>
<s-badge tone="critical" icon="arrow-down">
0.8%
</s-badge>
</s-stack>
</s-grid>
</s-clickable>
</s-grid>
</s-section>
{/* === */}
{/* Callout card */}
{/* The dismiss button sits in the header's secondary-actions slot, beside the heading it dismisses. */}
{/* If dismissed, use local storage or a database entry to avoid showing this section again to the same user. */}
{/* === */}
{visible.calloutCard && (
<s-section heading="Ready to create your custom puzzle?">
<s-button
slot="secondary-actions"
onClick={() => setVisible({ ...visible, calloutCard: false })}
icon="x"
tone="neutral"
variant="tertiary"
accessibilityLabel="Dismiss card"
></s-button>
<s-grid
gridTemplateColumns="@container (inline-size <= 480px) 1fr, auto auto"
gap="base"
alignItems="center"
>
<s-grid gap="small-200">
<s-paragraph>
Start by uploading an image to your gallery or choose from one
of our templates.
</s-paragraph>
<s-stack direction="inline" gap="small-200">
<s-button>Upload image</s-button>
<s-button tone="neutral" variant="tertiary">
Browse templates
</s-button>
</s-stack>
</s-grid>
<s-stack alignItems="center">
<s-box maxInlineSize="200px">
<s-image
src="https://cdn.shopify.com/static/images/polaris/patterns/callout.png"
alt="Customize checkout illustration"
aspectRatio="1/0.5"
borderRadius="base"
/>
</s-box>
</s-stack>
</s-grid>
</s-section>
)}
{/* === */}
{/* Puzzle templates */}
{/* The link to every template is the section's action, so it sits in the secondary-actions slot. */}
{/* Each template is its own tile, so its image and its View action read as one item. */}
{/* === */}
<s-section heading="Puzzle templates">
<s-button slot="secondary-actions" href="/puzzles">
See all templates
</s-button>
<s-grid
gridTemplateColumns="repeat(auto-fit, minmax(155px, 1fr))"
gap="base"
>
{templates.map((template) => (
<s-box
key={template.id}
border="base"
borderRadius="base"
overflow="hidden"
>
<s-clickable
href={`/puzzles/${template.id}`}
accessibilityLabel={`${template.name} puzzle template`}
>
<s-image
aspectRatio="1/1"
objectFit="cover"
alt={`${template.name} puzzle template`}
src={template.image}
/>
</s-clickable>
<s-divider />
<s-grid
gridTemplateColumns="1fr auto"
padding="small"
gap="small"
alignItems="center"
>
<s-heading>{template.name}</s-heading>
<s-button
href={`/puzzles/${template.id}`}
accessibilityLabel={`View ${template.name} puzzle template`}
>
View
</s-button>
</s-grid>
</s-box>
))}
</s-grid>
</s-section>
{/* === */}
{/* News */}
{/* News items are rows separated by dividers, rather than bordered boxes inside the card. */}
{/* === */}
<s-section heading="News">
<s-button slot="secondary-actions" href="/news">
See all news
</s-button>
<s-stack gap="base">
{news.map((item, index) => (
<s-stack key={item.id} gap="base">
{index > 0 && <s-divider />}
<s-stack gap="small-400">
<s-text color="subdued">{item.date}</s-text>
<s-link href={`/news/${item.id}`}>
<s-heading>{item.title}</s-heading>
</s-link>
<s-paragraph>{item.summary}</s-paragraph>
</s-stack>
</s-stack>
))}
</s-stack>
</s-section>
{/* === */}
{/* Featured apps */}
{/* Each app is its own tile, two to a row on wider screens. The whole tile is the link, so it holds no button of its own. */}
{/* If dismissed, use local storage or a database entry to avoid showing this section again to the same user. */}
{/* === */}
{visible.featuredApps && (
<s-section heading="Featured apps">
<s-button
slot="secondary-actions"
onClick={() => setVisible({ ...visible, featuredApps: false })}
icon="x"
tone="neutral"
variant="tertiary"
accessibilityLabel="Dismiss featured apps"
></s-button>
<s-grid
gridTemplateColumns="repeat(auto-fit, minmax(240px, 1fr))"
gap="base"
>
{apps.map((app) => (
<s-clickable
key={app.href}
href={app.href}
target="_blank"
border="base"
borderRadius="base"
padding="base"
accessibilityLabel={`Get ${app.name} on the Shopify App Store`}
>
<s-grid
gridTemplateColumns="auto 1fr auto"
alignItems="start"
gap="base"
>
<s-thumbnail size="small" src={app.icon} alt="" />
<s-box>
<s-heading>{app.name}</s-heading>
<s-paragraph color="subdued">Free</s-paragraph>
<s-paragraph color="subdued">{app.description}</s-paragraph>
</s-box>
<s-icon type="external" />
</s-grid>
</s-clickable>
))}
</s-grid>
</s-section>
)}
{/* Footer help */}
<s-stack alignItems="center" paddingBlock="large">
<s-text color="subdued">
Learn more about <s-link href="https://help.shopify.com" target="_blank">creating engaging puzzles</s-link>.
</s-text>
</s-stack>
</s-page>
)html
<!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-2.0-rc.js"></script>
<title>Pattern</title>
<script>
// Simple global object to store handlers
window.puzzleApp = {
progress: 0,
// Banner handlers
dismissBanner: function(bannerElement) {
if (bannerElement) {
bannerElement.style.display = 'none';
}
},
// Guide handlers
dismissGuide: function(guideSection) {
if (guideSection) {
guideSection.style.display = 'none';
}
},
// Step handlers
toggleStep: function(button, detailsContainer) {
if (button && detailsContainer) {
const isExpanded = detailsContainer.style.display !== 'none';
detailsContainer.style.display = isExpanded ? 'none' : '';
button.setAttribute('icon', isExpanded ? 'chevron-down' : 'chevron-up');
}
},
// Checkbox handlers
updateProgress: function(checkbox, progressElement) {
if (checkbox && progressElement) {
this.progress += checkbox.checked ? 1 : -1;
progressElement.textContent = `${this.progress} of 3 steps completed`;
}
},
// Section dismissal handlers
dismissSection: function(section) {
if (section) {
section.style.display = 'none';
}
}
};
</script>
</head>
<body>
<!-- === -->
<!-- Home page pattern -->
<!-- === -->
<s-page>
<s-button slot="primary-action" variant="primary">Create puzzle</s-button>
<s-button slot="secondary-actions">Browse templates</s-button>
<s-button slot="secondary-actions">Import image</s-button>
<!-- === -->
<!-- Banner -->
<!-- Use banners sparingly. Only one banner should be visible at a time. -->
<!-- If dismissed, use local storage or a database entry to avoid showing this section again to the same user. -->
<!-- === -->
<s-banner
id="upgrade-banner"
dismissible
onDismiss="window.puzzleApp.dismissBanner(this)"
>
3 of 5 puzzles created.
<s-link href="#">Upgrade to Puzzlify Pro</s-link> to create unlimited puzzles.
</s-banner>
<!-- === -->
<!-- Setup guide -->
<!-- Keep instructions brief and direct. Only ask merchants for required information. -->
<!-- The header holds the guide's progress in the supplemental slot and its dismiss button in the secondary-actions slot. -->
<!-- Steps sit directly in the card, separated by dividers. A step's details open beneath it, in line with its label, without a box of their own. -->
<!-- If dismissed, use local storage or a database entry to avoid showing this section again to the same user. -->
<!-- === -->
<s-section
id="setup-guide-section"
heading="Setup guide"
subheading="Use this personalized guide to get your store ready for sales."
>
<s-text slot="supplemental" id="progress-text" color="subdued">0 of 3 steps completed</s-text>
<s-button
slot="secondary-actions"
accessibilityLabel="Dismiss guide"
onClick="window.puzzleApp.dismissGuide(document.getElementById('setup-guide-section'))"
variant="tertiary"
tone="neutral"
icon="x"
></s-button>
<s-stack gap="small">
<!-- Step 1 -->
<s-grid gridTemplateColumns="1fr auto" gap="base" alignItems="center">
<s-checkbox
label="Upload an image for your puzzle"
onInput="window.puzzleApp.updateProgress(this, document.getElementById('progress-text'))"
></s-checkbox>
<s-button
onClick="window.puzzleApp.toggleStep(this, document.getElementById('step1-details'))"
accessibilityLabel="Toggle Upload an image for your puzzle details"
variant="tertiary"
icon="chevron-down"
></s-button>
</s-grid>
<s-grid
id="step1-details"
gridTemplateColumns="1fr auto"
gap="base"
alignItems="center"
paddingInlineStart="large-200"
style="display: none;"
>
<s-stack gap="small-200">
<s-paragraph color="subdued">
Start by uploading a high-quality image that will be used to create your
puzzle. For best results, use images that are at least 1200x1200 pixels.
</s-paragraph>
<s-stack direction="inline" gap="small-200">
<s-button variant="primary">Upload image</s-button>
<s-button variant="tertiary" tone="neutral">Image requirements</s-button>
</s-stack>
</s-stack>
<s-box maxBlockSize="80px" maxInlineSize="80px">
<s-image
src="https://cdn.shopify.com/s/assets/admin/checkout/settings-customizecart-705f57c725ac05be5a34ec20c05b94298cb8afd10aac7bd9c7ad02030f48cfa0.svg"
alt=""
></s-image>
</s-box>
</s-grid>
<!-- Step 2 -->
<s-divider></s-divider>
<s-grid gridTemplateColumns="1fr auto" gap="base" alignItems="center">
<s-checkbox
label="Choose a puzzle template"
onInput="window.puzzleApp.updateProgress(this, document.getElementById('progress-text'))"
></s-checkbox>
<s-button
onClick="window.puzzleApp.toggleStep(this, document.getElementById('step2-details'))"
accessibilityLabel="Toggle Choose a puzzle template details"
variant="tertiary"
icon="chevron-down"
></s-button>
</s-grid>
<s-grid
id="step2-details"
gridTemplateColumns="1fr auto"
gap="base"
alignItems="center"
paddingInlineStart="large-200"
style="display: none;"
>
<s-stack gap="small-200">
<s-paragraph color="subdued">
Select a template for your puzzle - choose between 9-piece (beginner),
16-piece (intermediate), or 25-piece (advanced) layouts.
</s-paragraph>
<s-stack direction="inline" gap="small-200">
<s-button variant="primary">Choose template</s-button>
<s-button variant="tertiary" tone="neutral">See all templates</s-button>
</s-stack>
</s-stack>
<s-box maxBlockSize="80px" maxInlineSize="80px">
<s-image
src="https://cdn.shopify.com/s/assets/admin/checkout/settings-customizecart-705f57c725ac05be5a34ec20c05b94298cb8afd10aac7bd9c7ad02030f48cfa0.svg"
alt=""
></s-image>
</s-box>
</s-grid>
<!-- Step 3 -->
<s-divider></s-divider>
<s-grid gridTemplateColumns="1fr auto" gap="base" alignItems="center">
<s-checkbox
label="Customize puzzle piece shapes"
onInput="window.puzzleApp.updateProgress(this, document.getElementById('progress-text'))"
></s-checkbox>
<s-button
onClick="window.puzzleApp.toggleStep(this, document.getElementById('step3-details'))"
accessibilityLabel="Toggle Customize puzzle piece shapes details"
variant="tertiary"
icon="chevron-down"
></s-button>
</s-grid>
<s-grid
id="step3-details"
gridTemplateColumns="1fr auto"
gap="base"
alignItems="center"
paddingInlineStart="large-200"
style="display: none;"
>
<s-stack gap="small-200">
<s-paragraph color="subdued">
Make your puzzle unique by customizing the shapes of individual pieces.
Choose from classic, curved, or themed piece styles.
</s-paragraph>
<s-stack direction="inline" gap="small-200">
<s-button variant="primary">Customize pieces</s-button>
<s-button variant="tertiary" tone="neutral">Learn about piece styles</s-button>
</s-stack>
</s-stack>
<s-box maxBlockSize="80px" maxInlineSize="80px">
<s-image
src="https://cdn.shopify.com/s/assets/admin/checkout/settings-customizecart-705f57c725ac05be5a34ec20c05b94298cb8afd10aac7bd9c7ad02030f48cfa0.svg"
alt=""
></s-image>
</s-box>
</s-grid>
<!-- Add additional steps here... -->
</s-stack>
</s-section>
<!-- === -->
<!-- Metrics cards -->
<!-- Your app homepage should provide merchants with quick statistics or status updates that help them understand how the app is performing for them. -->
<!-- A section with no visible heading still needs a name, so give it an accessibilityLabel. -->
<!-- === -->
<s-section accessibilityLabel="Puzzle metrics">
<s-grid
gridTemplateColumns="@container (inline-size <= 400px) 1fr, 1fr auto 1fr auto 1fr"
gap="small"
>
<s-clickable
href="#"
paddingBlock="small-400"
paddingInline="small-100"
borderRadius="base"
>
<s-grid gap="small-300">
<s-heading>Total Designs</s-heading>
<s-stack direction="inline" gap="small-200">
<s-text>156</s-text>
<s-badge tone="success" icon="arrow-up"> 12% </s-badge>
</s-stack>
</s-grid>
</s-clickable>
<s-divider direction="block"></s-divider>
<s-clickable
href="#"
paddingBlock="small-400"
paddingInline="small-100"
borderRadius="base"
>
<s-grid gap="small-300">
<s-heading>Units Sold</s-heading>
<s-stack direction="inline" gap="small-200">
<s-text>2,847</s-text>
<s-badge tone="warning">0%</s-badge>
</s-stack>
</s-grid>
</s-clickable>
<s-divider direction="block"></s-divider>
<s-clickable
href="#"
paddingBlock="small-400"
paddingInline="small-100"
borderRadius="base"
>
<s-grid gap="small-300">
<s-heading>Return Rate</s-heading>
<s-stack direction="inline" gap="small-200">
<s-text>3.2%</s-text>
<s-badge tone="critical" icon="arrow-down"> 0.8% </s-badge>
</s-stack>
</s-grid>
</s-clickable>
</s-grid>
</s-section>
<!-- === -->
<!-- Callout card -->
<!-- The dismiss button sits in the header's secondary-actions slot, beside the heading it dismisses. -->
<!-- If dismissed, use local storage or a database entry to avoid showing this section again to the same user. -->
<!-- === -->
<s-section id="callout-section" heading="Ready to create your custom puzzle?">
<s-button
slot="secondary-actions"
onClick="window.puzzleApp.dismissSection(document.getElementById('callout-section'))"
icon="x"
tone="neutral"
variant="tertiary"
accessibilityLabel="Dismiss card"
></s-button>
<s-grid
gridTemplateColumns="@container (inline-size <= 480px) 1fr, auto auto"
gap="base"
alignItems="center"
>
<s-grid gap="small-200">
<s-paragraph>
Start by uploading an image to your gallery or choose from one of our templates.
</s-paragraph>
<s-stack direction="inline" gap="small-200">
<s-button>Upload image</s-button>
<s-button tone="neutral" variant="tertiary">Browse templates</s-button>
</s-stack>
</s-grid>
<s-box maxInlineSize="200px">
<s-image
src="https://cdn.shopify.com/static/images/polaris/patterns/callout.png"
alt="Customize checkout illustration"
aspectRatio="1/0.5"
borderRadius="base"
></s-image>
</s-box>
</s-grid>
</s-section>
<!-- === -->
<!-- Puzzle templates -->
<!-- The link to every template is the section's action, so it sits in the secondary-actions slot. -->
<!-- Each template is its own tile, so its image and its View action read as one item. -->
<!-- === -->
<s-section heading="Puzzle templates">
<s-button slot="secondary-actions" href="/puzzles">See all templates</s-button>
<s-grid gridTemplateColumns="repeat(auto-fit, minmax(155px, 1fr))" gap="base">
<!-- Featured template 1 -->
<s-box border="base" borderRadius="base" overflow="hidden">
<s-clickable href="/puzzles/4-piece" accessibilityLabel="4-Pieces puzzle template">
<s-image
aspectRatio="1/1"
objectFit="cover"
alt="4-Pieces puzzle template"
src="https://cdn.shopify.com/static/images/polaris/patterns/4-pieces.png"
></s-image>
</s-clickable>
<s-divider></s-divider>
<s-grid gridTemplateColumns="1fr auto" padding="small" gap="small" alignItems="center">
<s-heading>4-Pieces</s-heading>
<s-button href="/puzzles/4-piece" accessibilityLabel="View 4-Pieces puzzle template">
View
</s-button>
</s-grid>
</s-box>
<!-- Featured template 2 -->
<s-box border="base" borderRadius="base" overflow="hidden">
<s-clickable href="/puzzles/9-piece" accessibilityLabel="9-Pieces puzzle template">
<s-image
aspectRatio="1/1"
objectFit="cover"
alt="9-Pieces puzzle template"
src="https://cdn.shopify.com/static/images/polaris/patterns/9-pieces.png"
></s-image>
</s-clickable>
<s-divider></s-divider>
<s-grid gridTemplateColumns="1fr auto" padding="small" gap="small" alignItems="center">
<s-heading>9-Pieces</s-heading>
<s-button href="/puzzles/9-piece" accessibilityLabel="View 9-Pieces puzzle template">
View
</s-button>
</s-grid>
</s-box>
<!-- Featured template 3 -->
<s-box border="base" borderRadius="base" overflow="hidden">
<s-clickable href="/puzzles/16-piece" accessibilityLabel="16-Pieces puzzle template">
<s-image
aspectRatio="1/1"
objectFit="cover"
alt="16-Pieces puzzle template"
src="https://cdn.shopify.com/static/images/polaris/patterns/16-pieces.png"
></s-image>
</s-clickable>
<s-divider></s-divider>
<s-grid gridTemplateColumns="1fr auto" padding="small" gap="small" alignItems="center">
<s-heading>16-Pieces</s-heading>
<s-button href="/puzzles/16-piece" accessibilityLabel="View 16-Pieces puzzle template">
View
</s-button>
</s-grid>
</s-box>
</s-grid>
</s-section>
<!-- === -->
<!-- News -->
<!-- News items are rows separated by dividers, rather than bordered boxes inside the card. -->
<!-- === -->
<s-section heading="News">
<s-button slot="secondary-actions" href="/news">See all news</s-button>
<s-stack gap="base">
<!-- News item 1 -->
<s-stack gap="small-400">
<s-text color="subdued">Jan 21, 2025</s-text>
<s-link href="/news/new-shapes-and-themes">
<s-heading>New puzzle shapes and themes added</s-heading>
</s-link>
<s-paragraph>
We've added 5 new puzzle piece shapes and 3 seasonal themes to help you create more
engaging and unique puzzles for your customers.
</s-paragraph>
</s-stack>
<s-divider></s-divider>
<!-- News item 2 -->
<s-stack gap="small-400">
<s-text color="subdued">Nov 6, 2024</s-text>
<s-link href="/news/puzzle-difficulty-customization">
<s-heading>Puzzle difficulty customization features</s-heading>
</s-link>
<s-paragraph>
Now you can fine-tune the difficulty of your puzzles with new rotation controls, edge
highlighting options, and piece recognition settings.
</s-paragraph>
</s-stack>
</s-stack>
</s-section>
<!-- === -->
<!-- Featured apps -->
<!-- Each app is its own tile, two to a row on wider screens. The whole tile is the link, so it holds no button of its own. -->
<!-- If dismissed, use local storage or a database entry to avoid showing this section again to the same user. -->
<!-- === -->
<s-section id="featured-apps-section" heading="Featured apps">
<s-button
slot="secondary-actions"
onClick="window.puzzleApp.dismissSection(document.getElementById('featured-apps-section'))"
icon="x"
tone="neutral"
variant="tertiary"
accessibilityLabel="Dismiss featured apps"
></s-button>
<s-grid gridTemplateColumns="repeat(auto-fit, minmax(240px, 1fr))" gap="base">
<!-- Featured app 1 -->
<s-clickable
href="https://apps.shopify.com/flow"
target="_blank"
border="base"
borderRadius="base"
padding="base"
accessibilityLabel="Get Shopify Flow on the Shopify App Store"
>
<s-grid gridTemplateColumns="auto 1fr auto" alignItems="start" gap="base">
<s-thumbnail
size="small"
src="https://cdn.shopify.com/app-store/listing_images/15100ebca4d221b650a7671125cd1444/icon/CO25r7-jh4ADEAE=.png"
alt=""
></s-thumbnail>
<s-box>
<s-heading>Shopify Flow</s-heading>
<s-paragraph color="subdued">Free</s-paragraph>
<s-paragraph color="subdued">Automate everything and get back to business.</s-paragraph>
</s-box>
<s-icon type="external"></s-icon>
</s-grid>
</s-clickable>
<!-- Featured app 2 -->
<s-clickable
href="https://apps.shopify.com/planet"
target="_blank"
border="base"
borderRadius="base"
padding="base"
accessibilityLabel="Get Shopify Planet on the Shopify App Store"
>
<s-grid gridTemplateColumns="auto 1fr auto" alignItems="start" gap="base">
<s-thumbnail
size="small"
src="https://cdn.shopify.com/app-store/listing_images/87176a11f3714753fdc2e1fc8bbf0415/icon/CIqiqqXsiIADEAE=.png"
alt=""
></s-thumbnail>
<s-box>
<s-heading>Shopify Planet</s-heading>
<s-paragraph color="subdued">Free</s-paragraph>
<s-paragraph color="subdued">Offer carbon-neutral shipping and showcase your commitment.</s-paragraph>
</s-box>
<s-icon type="external"></s-icon>
</s-grid>
</s-clickable>
</s-grid>
</s-section>
<!-- Footer help -->
<s-stack alignItems="center" paddingBlock="large">
<s-text color="subdued">Learn more about <s-link href="https://help.shopify.com" target="_blank">creating engaging puzzles</s-link>.</s-text>
</s-stack>
</s-page>
</body>
</html>