---
title: Migrate Breadcrumbs from Polaris React
description: >-
  Learn how to migrate Polaris React Breadcrumbs to Polaris web components in an
  embedded app.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/breadcrumbs
  md: >-
    https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/breadcrumbs.md
api_name: app-home
---

# Migrate Breadcrumbs from Polaris React

Polaris web components don't provide a standalone `Breadcrumbs` component. Place [`s-link`](https://shopify.dev/docs/api/app-home/web-components/actions/link) children in the [`s-page` `breadcrumb-actions` slot](https://shopify.dev/docs/api/app-home/web-components/layout-and-structure/page).

The Polaris React `Breadcrumbs` component from `@shopify/polaris` rendered one icon-only back action despite its plural name. The page slot can show the parent hierarchy with visible link labels and owns the breadcrumb presentation.

***

## Migrate the page and breadcrumb together

Most apps use the old breadcrumb through the Polaris React `Page` `backAction` property. Move the action into the destination page rather than rendering a breadcrumb as ordinary page content.

## Migrating a page back action to breadcrumb actions

##### Polaris web components

```tsx
export function EditProductPage() {
  return (
    <s-page heading="Edit product">
      <s-link slot="breadcrumb-actions" href="/products">
        Products
      </s-link>
      <s-section heading="Product details">
        <s-text>Update product information and availability.</s-text>
      </s-section>
    </s-page>
  );
}
```

##### Polaris React

```tsx
import {Card, Page, Text} from '@shopify/polaris';

export function EditProductPage() {
  return (
    <Page
      title="Edit product"
      backAction={{
        content: 'Products',
        url: '/products',
      }}
    >
      <Card>
        <Text as="h2" variant="headingSm">Product details</Text>
        <Text as="p">Update product information and availability.</Text>
      </Card>
    </Page>
  );
}
```

***

## Replace back​Action

Replace the `backAction` descriptor object with a slotted component. Prefer a link when the parent has a URL.

| Polaris React action field | Polaris web components |
| - | - |
| `content` | Move to the visible child text of `s-link`. |
| `url` | Rename to `href` on `s-link`. |
| `onAction` | Use `onClick` on the destination `s-link` only for necessary navigation guards. |
| `accessibilityLabel` | Keep as `accessibilityLabel` only when the visible label needs more context. |
| `id` | Keep `id` only when another element or app logic references it. |

Polaris React used `content` as the icon-only button's fallback accessible label. In the new slot, write a concise visible parent label such as **Products** or **Settings**. Don't use **Back** as the only text because it doesn't describe the destination.

### Link actions

Use `s-link` for hierarchy navigation. Set `slot="breadcrumb-actions"`, move `url` to `href`, and use the parent name as the visible child text. This gives merchants a stable destination and preserves expected link behavior such as opening in a new tab.

### Callback actions

The `breadcrumb-actions` slot accepts links, not buttons. If the old callback only calls `history.back()`, replace it with the parent URL. Breadcrumbs represent hierarchy, not the merchant's browser history.

If the callback guards unsaved changes, call [`shopify.saveBar.leaveConfirmation()`](https://shopify.dev/docs/api/app-home/apis/user-interface-and-interactions/save-bar-api) before navigating. Continue to the real parent `href` only when the promise resolves. Move callbacks that perform non-navigation actions into a supported page action slot.

***

## Add multiple parent levels

You can add more than one slotted `s-link` when the hierarchy helps merchants understand the current location. Put them in ancestor-to-parent order. Don't add the current page as a breadcrumb; `s-page` already displays it in `heading`. Keep the trail short enough to remain useful at narrow iframe widths.

***

## Removed component behavior

* Remove the imported `ArrowLeftIcon`; the page owns breadcrumb presentation.
* Remove pointer-down blur helpers and wrappers that only styled the old icon button.
* Don't render `Breadcrumbs` outside the page header and manually recreate its spacing.
* Don't keep a `backAction` compatibility object after all consumers render slotted links.

***

## Test the migration

* Follow every breadcrumb and confirm it reaches the intended parent, including routes with nested IDs or query parameters.
* Verify callback breadcrumbs preserve unsaved-change prompts and don't run twice.
* Test keyboard focus, visible labels, accessible names, and new-tab behavior.
* Check one-level and multi-level trails at narrow iframe widths.
* Confirm the current page heading isn't duplicated in the breadcrumb trail.
* Remove the Polaris React `Breadcrumbs` import, or the `Page` `backAction` object, after its final consumer is migrated.

***

## Related guidance

* [Page component](https://shopify.dev/docs/api/app-home/web-components/layout-and-structure/page)
* [Link component](https://shopify.dev/docs/api/app-home/web-components/actions/link)
* [Migrate Page from Polaris React](https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/page)
* [Migrate from Polaris React](https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react)

***
