Skip to main content

Migrate Navigation from Polaris React

Replace Polaris React Navigation with s-app-nav. App navigation renders in the Shopify admin rather than inside the app's Frame.

s-app-nav supports one level of s-link children. Flatten sections and nested items intentionally instead of reproducing the old navigation hierarchy.


Anchor to Migrate primary navigationMigrate primary navigation

Migrating primary app navigation

function AppNavigation() {
return (
<s-app-nav>
<s-link href="/products">Products</s-link>
<s-link href="/settings">Settings</s-link>
</s-app-nav>
);
}
import {Navigation} from '@shopify/polaris';

export function AppNavigation() {
return (
<Navigation location="/products">
<Navigation.Section
items={[
{label: 'Home', url: '/'},
{label: 'Products', url: '/products'},
{label: 'Settings', url: '/settings'},
]}
/>
</Navigation>
);
}

s-app-nav renders only in the Shopify admin shell, so this admin navigation example isn't available as an isolated live preview.

Keep s-app-nav mounted near the app root rather than rendering a different navigation component for each route.


Anchor to Map navigation itemsMap navigation items

Polaris ReactPolaris web componentsMigration notes
Navigation.SectionRemoves-app-nav doesn't display section containers or headings.
itemss-link childrenRender each primary destination as a link.
Item labelLink textUse a concise noun that matches the destination page title.
Item urlhrefPreserve a real URL for direct and modified navigation.
location and item selectedRemoveThe host derives the active destination from the current URL.
Item onClickLink navigation or a page-level actionKeep navigation declarative. Move non-navigation actions out of app nav.
Item icon, badge, exactMatch, or matchPathsRemoveThe destination doesn't expose these presentation and matching controls.

Anchor to Flatten nested navigationFlatten nested navigation

s-app-nav doesn't support nested items. For each subNavigationItems tree, choose one of these migrations:

  • Promote frequently used destinations to top-level app-nav links.
  • Keep one top-level link and move child destinations into the landing page.
  • Use page-level tabs or links when the destinations are alternate views of one resource.
  • Remove destinations that duplicate breadcrumbs, page actions, or contextual resource links.

Don't encode hierarchy into labels such as Products > Collections. Use concise labels and make the destination page establish its own context.


Anchor to Preserve router behaviorPreserve router behavior

Use href values that the embedded app router can resolve directly. Verify direct loads, browser back and forward navigation, copied URLs, and modified clicks. Don't replace links with click handlers that call the router unless the control isn't navigation.

If the app mounts below a path such as /app, then include that base path consistently in every destination. The App nav reference documents rel="home" specifically for links inside s-app-nav:

<s-app-nav>
<s-link href="/app" rel="home">Home</s-link>
<s-link href="/app/products">Products</s-link>
<s-link href="/app/settings">Settings</s-link>
</s-app-nav>

The rel="home" link sets the non-root home route for the app name in Shopify admin; it doesn't render a visible Home navigation item. Generic s-link JSX types don't expose rel, so keep this App nav-specific pattern in markup rather than reusing it on links elsewhere.


Anchor to Remove the Frame dependencyRemove the Frame dependency

Polaris React passed Navigation to the navigation prop on Frame. Render s-app-nav near the app root, and remove Frame state used only to open or dismiss mobile navigation. The Shopify admin owns the surrounding responsive shell.


  • Visit every destination through app nav and by loading its URL directly.
  • Verify the active destination follows route changes and browser history.
  • Test modified clicks, opening links in a new tab, and copied URLs.
  • Confirm that nested destinations remain discoverable after flattening.
  • Resize the app, and confirm that app nav doesn't duplicate an in-iframe navigation shell.

Anchor to Remove Polaris ReactRemove Polaris React

After every Navigation call site is migrated, remove Navigation, its Frame prop, mobile-navigation state, and imported navigation icons used only by it. Remove @shopify/polaris only after no other route in scope imports it.



Was this page helpful?