Skip to content

Page

Skeleton page is used with other skeleton loading components to provide a low fidelity representation of the user interface (UI) before content appears on the page. It improves load times perceived by merchants.

Use for detail pages, which should have pagination and breadcrumbs, and also often have several actions.

vue
<template>
<Page
  title="3/4 inch Leather pet collar"
  subtitle="Perfect for any pet"
  compactTitle
  :backAction="{ content: 'Products', url: '#' }"
  :primaryAction="{ content: 'Save', disabled: true }"
  :secondaryActions="[
    {
      content: 'Duplicate',
      accessibilityLabel: 'Secondary action label',
      onAction: () => console.log('Duplicate action'),
    },
    {
      content: 'View on your store',
      onAction: () => console.log('View on your store action'),
    },
  ]"
  :actionGroups="[
    {
      title: 'Promote',
      actions: [
        {
          content: 'Share on Facebook',
          accessibilityLabel: 'Individual action label',
          onAction: () => console.log('Share on Facebook action'),
        },
      ],
    },
  ]"
  :pagination="{
    hasPrevious: true,
    hasNext: true,
  }"
>
  <template #pageTitle>
    <Badge tone="success">Paid</Badge>
  </template>
  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
</Page>
</template>
vue
<template>
<Page
  :backAction="{ content: 'Settings', url: '#' }"
  title="General"
>
  <template #primaryAction>
    <Button variant="primary">Save</Button>
  </template>

  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
</Page>
</template>
vue
<template>
<Page
  :backAction="{ content: 'Settings', url: '#' }"
  title="#1085"
  :secondaryActions="[
    {content: 'Print'},
    {content: 'Unarchive'},
    {content: 'Cancel order'},
  ]"
  :pagination="{
    hasPrevious: true,
    hasNext: true,
  }"
>
  <LegacyCard sectioned title="Fulfill order">
    <LegacyStack alignment="center">
      <LegacyStackItem fill>
        <p>Buy postage and ship remaining 2 items</p>
      </LegacyStackItem>
      <Button variant="primary">Continue</Button>
    </LegacyStack>
  </LegacyCard>
</Page>
</template>
vue
<template>
<Page
  title="General"
  :secondaryActions="[{content: 'Delete', destructive: true}]"
>
  <Text as="p">Page content</Text>
</Page>
</template>
vue
<template>
<Page title="General">
  <template #secondaryActions>
    <Button>Save</Button>
  </template>
  <Text as="p">Page content</Text>
</Page>
</template>
vue
<template>
<Page
  title="Product"
  :primaryAction="{
    content: 'Save',
  }"
  :secondaryActions="[{
    content: 'Import',
    disabled: true,
    helpText: 'You need permission to import products.',
  }]"
/>
</template>
vue
<template>
<Page
  title="Invoice"
  subtitle="Statement period: May 3, 2019 to June 2, 2019"
  :backAction="{content: 'Products', url: '#'}"
  :secondaryActions="[{content: 'Download', icon: ArrowDownIcon}]"
>
  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
</Page>
</template>

<script setup lang="ts">
import ArrowDownIcon from '@icons/ArrowDownIcon.svg'
</script>
vue
<template>
<Page
  title="Jar With Lock-Lid"
  :primaryAction="{content: 'Save', disabled: true}"
  :secondaryActions="[
    {
      content: 'Promote',
      external: true,
      icon: ExternalIcon,
      url: 'https://www.facebook.com/business/learn/facebook-page-build-audience',
    },
  ]"
>
  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
</Page>
</template>

<script setup lang="ts">
import ExternalIcon from '@icons/ExternalIcon.svg'
</script>
vue
<template>
<Page
    title="General"
    :backAction="{ content: 'Settings', url: '#' }"
    :primaryAction="{ content: 'Save' }"
>
  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
</Page>
</template>
vue
<template>
<Page
  fullWidth
  title="Orders"
  :primaryAction="{content: 'Create order', icon: PlusIcon}"
  :secondaryActions="[{content: 'Export'}]"
  :pagination="{
    hasNext: true,
  }"
>
  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
</Page>
</template>

<script setup lang="ts">
import PlusIcon from '@icons/PlusIcon.svg';
</script>
vue
<template>
<Page
  narrowWidth
  title="Add payment method"
  :backAction="{ content: 'Orders', url: '#' }"
  :primaryAction="{ content: 'Save', disabled: true }"
>
  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
  <PageActions
    :primaryAction="{ content: 'Save', disabled: true }"
    :secondaryActions="[{ content: 'Delete' }]"
  />
</Page>
</template>
vue
<template>
<Page
  title="Products"
  :actionGroups="[
    {
      title: 'Copy',
      onClick: () => {
        console.log('Copy action');
      },
      actions: [{ content: 'Copy to clipboard' }],
    },
    {
      title: 'Promote',
      disabled: true,
      actions: [{ content: 'Share on Facebook' }],
    },
    {
      title: 'More actions',
      actions: [
        { content: 'Duplicate' },
        { content: 'Print' },
        { content: 'Unarchive' },
        { content: 'Cancel order' },
      ],
    },
  ]"
>
  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
</Page>
</template>
vue
<template>
<Page
  title="Jar With Lock-Lid"
  :backAction="{ content: 'Products', url: '#' }"
  :primaryAction="{ content: 'Save', disabled: true }"
  :secondaryActions="[
    { content: 'Duplicate' },
    { content: 'View on your store' },
  ]"
  :pagination="{
    hasPrevious: true,
    hasNext: true,
  }"
>
  <template #pageTitle>
    <Badge tone="attention">Verified</Badge>
  </template>
  <LegacyCard title="Credit card" sectioned>
    <Text as="p">Credit card information</Text>
  </LegacyCard>
</Page>
</template>

Props

No props found for this component, run `yarn gen:docs` to generate component meta first.

Slots

No slots found for this component, run `yarn gen:docs` to generate component meta first.

Best practices

The page component should:

  • Always provide a title for the page header.
  • Always provide breadcrumbs when a page has a parent page.
  • Be organized around a primary activity. If that primary activity is a single action, provide it as a primary button in the page header.
  • Provide other page-level actions as secondary actions in the page header.
  • When the page represents an object of a certain type, provide pagination links to the previous and next object of the same type.

Content guidelines

Title

Titles should:

  • Describe the page in as few words as possible.
  • Be the name of the object type (pluralized) when the page is a list of objects. For a list of orders, the page title should be “Orders”.
  • Not be truncated.

App icon

App icons should:

  • Provide their app icon
  • Only be provided for pages that are part of a Shopify app

The content of each breadcrumb link should be the title of the page to which it links.

Page header actions

Page header action labels should be:

  • Clear and predictable: merchants should be able to anticipate what will happen when they click a page action. Never deceive merchants by mislabeling an action.

  • Action-led: they should always lead with a strong verb that encourages action. To provide enough context to merchants, use the {verb}+{noun} format.

Do

  • Create order
  • View in Postmates

Don’t

  • Create
  • Postmates deliveries
  • Short: for secondary actions, when the noun represents the same object as the page itself, a verb alone may be used. If there is ambiguity (such as with the verb “Cancel”), always use the {verb}+{noun} format.

    In the context of the orders list page:

Do

  • Import
  • Export

Don’t

  • Import orders
  • Export orders
  • Scannable: avoid unnecessary words and articles such as the, an, or a.

Do

Add menu item

Don’t

Add a menu item


Released under the MIT License.