Navigation API
The Navigation API lets you navigate between extension routes, other extensions, or host pages within customer accounts. Use this API to build multi-route extensions, link to specific customer account pages, or direct customers to other installed extensions.
The API supports several custom protocols:
shopify:customer-account/: Navigates to built-in customer account host pages such as orders or profile.extension://: Navigates within the current extension's routes.extension://<handle>: Navigates to a different installed extension by its handle.
Anchor to Use casesUse cases
- Build multi-page extensions: Use
extension://routes to create extensions with multiple views, such as a subscription management page with a settings sub-page. - Link to customer account pages: Navigate customers to built-in pages like order details or profile settings using the
shopify:customer-account/protocol. - Connect related extensions: Deep-link from one extension to another using
extension://<handle>when workflows span multiple extensions.
Supported targets
- customer-account.
footer. render-after - customer-account.
order-index. announcement. render - customer-account.
order-index. block. render - customer-account.
order-status. announcement. render - customer-account.
order-status. block. render - customer-account.
order-status. cart-line-item. render-after - customer-account.
order-status. cart-line-list. render-after - customer-account.
order-status. customer-information. render-after - customer-account.
order-status. fulfillment-details. render-after - customer-account.
order-status. payment-details. render-after - customer-account.
order-status. return-details. render-after - customer-account.
order-status. unfulfilled-items. render-after - customer-account.
order. action. menu-item. render - customer-account.
order. action. render - customer-account.
order. page. render - customer-account.
page. render - customer-account.
profile. addresses. render-after - customer-account.
profile. announcement. render - customer-account.
profile. block. render - customer-account.
profile. company-details. render-after - customer-account.
profile. company-location-addresses. render-after - customer-account.
profile. company-location-payment. render-after - customer-account.
profile. company-location-staff. render-after - customer-account.
profile. payment. render-after
Supported targets
- customer-account.
footer. render-after - customer-account.
order-index. announcement. render - customer-account.
order-index. block. render - customer-account.
order-status. announcement. render - customer-account.
order-status. block. render - customer-account.
order-status. cart-line-item. render-after - customer-account.
order-status. cart-line-list. render-after - customer-account.
order-status. customer-information. render-after - customer-account.
order-status. fulfillment-details. render-after - customer-account.
order-status. payment-details. render-after - customer-account.
order-status. return-details. render-after - customer-account.
order-status. unfulfilled-items. render-after - customer-account.
order. action. menu-item. render - customer-account.
order. action. render - customer-account.
order. page. render - customer-account.
page. render - customer-account.
profile. addresses. render-after - customer-account.
profile. announcement. render - customer-account.
profile. block. render - customer-account.
profile. company-details. render-after - customer-account.
profile. company-location-addresses. render-after - customer-account.
profile. company-location-payment. render-after - customer-account.
profile. company-location-staff. render-after - customer-account.
profile. payment. render-after
Anchor to PropertiesProperties
The shopify global object provides the navigation interface for customer account extensions. Access the following properties on shopify.navigation to navigate between pages, manage history, and handle navigation events.
- (type: "currententrychange", cb: (event: NavigationCurrentEntryChangeEvent) => void) => void(type: "currententrychange", cb: (event: NavigationCurrentEntryChangeEvent) => void) => voidrequiredrequired
Registers a listener that fires whenever the current navigation entry changes, such as when the buyer navigates to a different page.
- NavigationHistoryEntryNavigationHistoryEntryrequiredrequired
The current navigation history entry, representing the page the buyer is viewing. Only available in full-page extensions.
- NavigateFunctionNavigateFunctionrequiredrequired
Navigates to a URL, updating any provided state in the history entries list. Supports custom protocols for navigating within customer accounts.
- (type: "currententrychange", cb: (event: NavigationCurrentEntryChangeEvent) => void) => void(type: "currententrychange", cb: (event: NavigationCurrentEntryChangeEvent) => void) => voidrequiredrequired
Removes a previously registered
currententrychangelistener.- (options: NavigationUpdateCurrentEntryOptions) => void(options: NavigationUpdateCurrentEntryOptions) => voidrequiredrequired
Updates the state of the current history entry without triggering a navigation. Use this when the state change is independent of a page transition, such as saving form progress.
NavigationCurrentEntryChangeEvent
The event object passed to `currententrychange` listeners when the current navigation entry changes.
- from
The history entry the buyer navigated away from.
NavigationHistoryEntry - navigationType
The type of navigation that caused the change: `'push'`, `'replace'`, or `'traverse'`.
NavigationTypeString
NavigationHistoryEntry
A single entry in the navigation history stack. Each entry has a unique key, a URL, and optional developer-defined state.
- getState
Returns a clone of the developer-defined state associated with this history entry.
() => unknown - key
A unique, platform-generated identifier for this entry's position in the history stack. This value identifies the slot, not the content.
string - url
The URL associated with this history entry, or `null` if unavailable.
string | null
NavigationTypeString
An enumerated value representing the type of navigation.
'push' | 'replace' | 'traverse'NavigateFunction
A callable function that navigates to a URL within customer accounts. Accepts a destination URL and optional navigation options.
NavigationUpdateCurrentEntryOptions
Options for `Navigation.updateCurrentEntry()`. Use this to update the state of the current history entry without triggering a navigation.
- state
Developer-defined state to associate with the current navigation history entry.
unknown
jsx
Examples
Description
Navigate to a route within the current extension using the `extension://` protocol. This example renders a button that navigates to the `orders` path inside the extension when clicked.
jsx
import '@shopify/ui-extensions/preact'; import {render} from 'preact'; export default async () => { render(<Extension />, document.body); }; function Extension() { return ( <s-button onClick={() => { navigation.navigate('extension://orders'); }} > Navigate to orders path </s-button> ); }Description
Link to built-in customer account pages using the `shopify:customer-account/` protocol. This example renders buttons that navigate to the orders list and profile pages.
jsx
import '@shopify/ui-extensions/preact'; import {render} from 'preact'; export default async () => { render(<Extension />, document.body); }; function Extension() { return ( <s-stack direction="inline" gap="base"> <s-button onClick={() => { shopify.navigation.navigate( 'shopify:customer-account/orders', ); }} > View all orders </s-button> <s-button onClick={() => { shopify.navigation.navigate( 'shopify:customer-account/profile', ); }} > Edit profile </s-button> </s-stack> ); }Description
Deep-link to a different installed extension using the `extension://<handle>` protocol. This example navigates to a loyalty rewards extension when the customer clicks a button in a banner.
jsx
import '@shopify/ui-extensions/preact'; import {render} from 'preact'; export default async () => { render(<Extension />, document.body); }; function Extension() { function handleNavigate() { shopify.navigation.navigate( 'extension://loyalty-rewards', ); } return ( <s-banner heading="Loyalty program"> <s-text> You have 1,200 points available. </s-text> <s-button onClick={handleNavigate}> View rewards </s-button> </s-banner> ); }
Anchor to Best practicesBest practices
- Use custom protocols instead of absolute URLs: Always use
extension://,shopify:customer-account/, orextension://<handle>protocols rather than hardcoded URLs. Custom protocols ensure your extension works across different store domains and environments. - Provide a way back: When navigating to sub-routes within your extension, always include a navigation action that lets customers return to the previous view.
- Listen for navigation events when rendering depends on the route: Use
shopify.navigation.currentEntryor listen forcurrententrychangeevents to update your UI when the route changes, rather than relying on stale state.
Anchor to LimitationsLimitations
- The Navigation API can only navigate within the customer accounts surface. It can't redirect to external URLs or the storefront.
- The
extension://<handle>protocol requires the target extension to be installed and active on the store. If the target extension isn't available, the navigation call has no effect. - Navigation between extensions doesn't support passing custom data or query parameters beyond what the target extension's URL structure supports.