---
title: Migrate Link from Polaris React
description: >-
  Replace Polaris React Link with s-link while preserving real URLs, internal
  and external navigation, downloads, and accessible link text.
source_url:
  html: 'https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/link'
  md: >-
    https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/link.md
api_name: app-home
---

# Migrate Link from Polaris React

Replace Polaris React `Link` with [`s-link`](https://shopify.dev/docs/api/app-home/web-components/actions/link). Keep a real `href` so browser navigation, modified clicks, copying, and link announcements continue to work.

***

## Migrate an inline link

## Migrating links in content

##### Polaris web components

```html
<s-text>Review the <s-link href="/app/products">products requiring attention</s-link>.</s-text>
```

##### Polaris React

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

<Text as="p">
  Review the <Link url="/app/products">products requiring attention</Link>.
</Text>
```

***

## Replace Link properties

| Polaris React | Polaris web components | Migration notes |
| - | - | - |
| `url` | `href` | Preserve internal query strings and fragments. |
| `external` | `target="_blank"` when the destination leaves the embedded app | Don't open internal app routes in a new tab. |
| `download` | `download` | Keep `href` and verify response headers and filename. |
| `onClick` | `onClick` only for navigation-related instrumentation or guards | Don't replace `href` with a client-side click handler. |
| `accessibilityLabel` | `accessibilityLabel` only when visible text is insufficient | Prefer descriptive visible link text. |
| `monochrome` and `removeUnderline` | Remove | Let context and the destination component own link appearance. |
| `dataPrimaryLink` | Put the explicit resource link in the primary content | Don't make an entire row ambiguously clickable. |

Use `s-button` when the control mutates data, submits, or changes local UI without navigating. Text such as **Click here** or **Learn more** needs surrounding context to be meaningful; prefer link text that names the destination.

For navigation inside an embedded app, keep the app route in `href` and verify App Bridge routing, browser history, and unsaved-change protection. Before programmatic navigation with dirty state, use the Save Bar API's leave confirmation.

***

## Test the migration

* Open internal links normally and with modified or middle clicks.
* Verify external links and downloads use the intended target and response.
* Use browser back and forward navigation inside the embedded app.
* Check link purpose out of context with a screen reader.
* Confirm unsaved forms block or allow navigation according to product rules.

***

## Remove Polaris React

Remove `Link`, client-router adapters used only by Polaris, and click handlers that duplicated native navigation. Remove `@shopify/polaris` only after no other route in scope imports it.

***

## Related guidance

* [Link component](https://shopify.dev/docs/api/app-home/web-components/actions/link)
* [Migrate UnstyledLink from Polaris React](https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/unstyled-link)
* [Migrate Button from Polaris React](https://shopify.dev/docs/apps/build/app-home/migrate-from-polaris-react/button)

***
