--- title: Buyer Journey API description: The API for interacting with the buyer journey. api_version: 2026-04 api_name: checkout-ui-extensions source_url: html: >- https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/buyer-journey-api md: >- https://shopify.dev/docs/api/checkout-ui-extensions/latest/target-apis/checkout-apis/buyer-journey-api.md --- # Buyer Journey API The API for interacting with the buyer journey. ### Support Targets (31) ### Supported targets * purchase.​checkout.​actions.​render-before * purchase.​checkout.​block.​render * purchase.​checkout.​cart-line-item.​render-after * purchase.​checkout.​cart-line-list.​render-after * purchase.​checkout.​chat.​render * purchase.​checkout.​contact.​render-after * purchase.​checkout.​delivery-address.​render-after * purchase.​checkout.​delivery-address.​render-before * purchase.​checkout.​footer.​render-after * purchase.​checkout.​header.​render-after * purchase.​checkout.​payment-method-list.​render-after * purchase.​checkout.​payment-method-list.​render-before * purchase.​checkout.​pickup-location-list.​render-after * purchase.​checkout.​pickup-location-list.​render-before * purchase.​checkout.​pickup-location-option-item.​render-after * purchase.​checkout.​pickup-point-list.​render-after * purchase.​checkout.​pickup-point-list.​render-before * purchase.​checkout.​reductions.​render-after * purchase.​checkout.​reductions.​render-before * purchase.​checkout.​shipping-option-item.​details.​render * purchase.​checkout.​shipping-option-item.​render-after * purchase.​checkout.​shipping-option-list.​render-after * purchase.​checkout.​shipping-option-list.​render-before * purchase.​thank-you.​announcement.​render * purchase.​thank-you.​block.​render * purchase.​thank-you.​cart-line-item.​render-after * purchase.​thank-you.​cart-line-list.​render-after * purchase.​thank-you.​chat.​render * purchase.​thank-you.​customer-information.​render-after * purchase.​thank-you.​footer.​render-after * purchase.​thank-you.​header.​render-after ## StandardApi The base API object provided to `purchase` extension targets. * **buyerJourney** **BuyerJourney** **required** Provides details on the buyer's progression through the checkout and lets you intercept navigation to validate data before the buyer continues. Refer to [buyer journey](https://shopify.dev/docs/api/checkout-ui-extensions/2026-04/apis/buyer-journey#examples) examples for more information. ### BuyerJourney Provides details on the buyer's progression through the checkout. * activeStep The step of checkout the buyer is currently on. The value is \`undefined\` if the current step can't be determined. ```ts SubscribableSignalLike ``` * completed Whether the buyer has completed submitting their order. When \`true\`, the buyer is on the order status page after submitting payment. When \`false\`, the buyer is still in the checkout flow. ```ts SubscribableSignalLike ``` * intercept Installs a function for intercepting and preventing progress on checkout. This returns a promise that resolves to a teardown function. Calling the teardown function removes the interceptor. To block checkout progress, you must set the \[block\_progress]\(/docs/api/checkout-ui-extensions/2026-04/configuration#block-progress) capability in your extension's configuration. If you do, then you're expected to inform the buyer why navigation was blocked, either by passing validation errors to the checkout UI or rendering the errors in your extension. If the merchant hasn't allowed your extension to block checkout progress, show a warning in the \[checkout editor]\(/docs/apps/build/checkout/test-checkout-ui-extensions#test-the-extension-in-the-checkout-editor). ```ts (interceptor: Interceptor) => Promise<() => void> ``` * steps All possible steps the buyer can take to complete checkout. These steps vary depending on whether the checkout is one-page or three-page, and on the shop's configuration. ```ts SubscribableSignalLike ``` ### SubscribableSignalLike Represents a reactive signal interface that provides both immediate value access and subscription-based updates. Enables real-time synchronization with changing data through the observer pattern. This interface extends \`ReadonlySignalLike\` with deprecated fields that are still supported for backwards compatibility. * current The current value of the signal. Equivalent to \`.value\`, accessing this property subscribes to changes when used in a reactive context. ```ts T ``` * destroy Cleans up the subscription and releases any resources held by this signal. After calling \`destroy()\`, the signal stops receiving updates from the main thread. ```ts () => Promise ``` * subscribe Subscribes to value changes and calls the provided function whenever the value updates. Returns an unsubscribe function to clean up the subscription. Use to automatically react to changes in the signal's value. ```ts (fn: (value: T) => void) => () => void ``` * value The current value of the signal. This property provides immediate access to the current value without requiring subscription setup. Use for one-time value checks or initial setup. ```ts T ``` ### BuyerJourneyStepReference What step of checkout the buyer is currently on. * handle The handle identifying which step the buyer is on, such as \`'information'\`, \`'shipping'\`, or \`'payment'\`. See \`BuyerJourneyStepHandle\` for all values. ```ts BuyerJourneyStepHandle ``` ### BuyerJourneyStepHandle \| handle | Description | |---|---| | \`cart\` | The cart page. | | \`checkout\` | A one-page checkout, including Shop Pay. | | \`information\` | The contact information step of a three-page checkout. | | \`shipping\` | The shipping step of a three-page checkout. | | \`payment\` | The payment step of a three-page checkout. | | \`review\` | The step after payment where the buyer confirms the purchase. Not all shops are configured to have a review step. | | \`thank-you\` | The page displayed after the purchase, thanking the buyer. | | \`unknown\` | An unknown step in the buyer journey. | ```ts 'cart' | 'checkout' | 'information' | 'shipping' | 'payment' | 'review' | 'thank-you' | 'unknown' ``` ### Interceptor A function for intercepting and preventing navigation on checkout. You can block navigation by returning an object with \`{behavior: 'block', reason: 'your reason here', errors?: ValidationError\[]}\`. If you do, then you're expected to also update some part of your UI to reflect the reason why navigation was blocked, either by targeting checkout UI fields, passing errors to the page level, or rendering the errors in your extension. * interceptorProps ```ts InterceptorProps ``` InterceptorRequest | Promise\ ```ts InterceptorRequest | Promise ``` ### InterceptorProps * canBlockProgress Whether the interceptor can block the buyer's progress through checkout. When \`true\`, the merchant has granted your extension the \`block\_progress\` capability. When \`false\`, you can still validate but can't prevent the buyer from continuing. ```ts boolean ``` ### InterceptorRequest ```ts InterceptorRequestAllow | InterceptorRequestBlock ``` ### InterceptorRequestAllow * behavior Indicates that the interceptor allows the buyer's journey to continue. ```ts 'allow' ``` * perform This callback is called when all interceptors finish. We recommend setting errors or reasons for blocking at this stage, so that all the errors in the UI show up at once. ```ts (result: InterceptorResult) => void | Promise ``` ### InterceptorResult ```ts InterceptorResultAllow | InterceptorResultBlock ``` ### InterceptorResultAllow * behavior Indicates that the buyer was allowed to progress through checkout. ```ts 'allow' ``` ### InterceptorResultBlock * behavior Indicates that some part of the checkout UI intercepted and prevented the buyer's progress. The buyer typically needs to take some action to resolve this issue and to move on to the next step. ```ts 'block' ``` ### InterceptorRequestBlock * behavior Indicates that the interceptor blocks the buyer's journey from continuing. ```ts 'block' ``` * errors Used to pass errors to the checkout UI, outside your extension's UI boundaries. ```ts ValidationError[] ``` * perform This callback is called when all interceptors finish. We recommend setting errors or reasons for blocking at this stage, so that all the errors in the UI show up at once. ```ts (result: InterceptorResult) => void | Promise ``` * reason The reason for blocking the interceptor request. This value isn't presented to the buyer, so it doesn't need to be localized. The value is used only for Shopify's own internal debugging and metrics. ```ts string ``` ### ValidationError * message The error message to display to the buyer. Use this to explain what went wrong and how to fix it. ```ts string ``` * target The checkout UI field that the error is associated with. When provided, checkout highlights the matching field so the buyer knows where to fix the issue. The value is \`undefined\` if the error isn't tied to a specific field. ```ts string ``` ### BuyerJourneyStep * disabled Whether this step is disabled. When \`true\`, the buyer hasn't reached this step yet and can't navigate to it. When \`false\`, the step is accessible. For example, if the buyer hasn't reached the \`shipping\` step yet, then \`shipping\` is disabled. ```ts boolean ``` * handle The handle that uniquely identifies the buyer journey step, such as \`'information'\`, \`'shipping'\`, or \`'payment'\`. ```ts BuyerJourneyStepHandle ``` * label The localized label of the buyer journey step, suitable for rendering in navigation UI. ```ts string ``` * to The URL of the buyer journey step, using the \`shopify:\` protocol. ```ts string ``` ## use​Buyer​Journey() Returns the buyerJourney details on buyer progression in checkout. ### Returns * **BuyerJourney** ### ### BuyerJourneyProvides details on the buyer's progression through the checkout. * **activeStep** **SubscribableSignalLike\** The step of checkout the buyer is currently on. The value is `undefined` if the current step can't be determined. * **completed** **SubscribableSignalLike\** Whether the buyer has completed submitting their order. When `true`, the buyer is on the order status page after submitting payment. When `false`, the buyer is still in the checkout flow. * **intercept** **(interceptor: Interceptor) => Promise<() => void>** Installs a function for intercepting and preventing progress on checkout. This returns a promise that resolves to a teardown function. Calling the teardown function removes the interceptor. To block checkout progress, you must set the [block\_progress](https://shopify.dev/docs/api/checkout-ui-extensions/2026-04/configuration#block-progress) capability in your extension's configuration. If you do, then you're expected to inform the buyer why navigation was blocked, either by passing validation errors to the checkout UI or rendering the errors in your extension. If the merchant hasn't allowed your extension to block checkout progress, show a warning in the [checkout editor](https://shopify.dev/docs/apps/build/checkout/test-checkout-ui-extensions#test-the-extension-in-the-checkout-editor). * **steps** **SubscribableSignalLike\** All possible steps the buyer can take to complete checkout. These steps vary depending on whether the checkout is one-page or three-page, and on the shop's configuration. ## use​Buyer​Journey​Completed() Returns `true` if the buyer completed submitting their order. For example, when viewing the **Order status** page after submitting payment, the buyer will have completed their order. ### Returns * **false | true** ## use​Buyer​Journey​Intercept(**[interceptor](#usebuyerjourneyintercept-propertydetail-interceptor)**​) Installs a function for intercepting and preventing progress on checkout. To block checkout progress, you must set the [block\_progress](https://shopify.dev/docs/api/checkout-ui-extensions/configuration#block-progress) capability in your extension's configuration. If you do, then you're expected to inform the buyer why navigation was blocked, either by passing validation errors to the checkout UI or rendering the errors in your extension. `useBuyerJourneyIntercept()` should be called at the top level of the extension, not within an embedded or child component, to avoid errors should the child component get destroyed. It is good practice to show a warning in the checkout editor when the merchant has not given permission for your extension to block checkout progress. ### Parameters * **interceptor** **Interceptor** **required** ### Returns**void** ## use​Buyer​Journey​Steps() Returns all possible steps a buyer can take to complete the checkout. These steps may vary depending on the type of checkout or the shop's configuration. ### Returns * **BuyerJourneyStep\[]** ## use​Buyer​Journey​Active​Step() Returns the buyer journey step that the buyer is currently on. ### Returns * **BuyerJourneyStep | undefined** Examples ### Examples * #### Block progress and show error for a checkout UI field ##### Description Intercept and prevent a buyer's progress through checkout while targeting a specific checkout UI field. See the \[validation tutorial]\(/docs/apps/checkout/validation) for more examples and best practices. ##### Preact ```jsx import '@shopify/ui-extensions/preact'; import {render} from 'preact'; import { useBuyerJourneyIntercept, useExtensionEditor, useExtensionCapability, } from '@shopify/ui-extensions/checkout/preact'; export default function extension() { render(, document.body); } function Extension() { const editorType = useExtensionEditor()?.type; const blockProgressGranted = useExtensionCapability('block_progress'); useBuyerJourneyIntercept( ({canBlockProgress}) => { return canBlockProgress && shopify.shippingAddress.value ?.countryCode && shopify.shippingAddress.value .countryCode !== 'CA' ? { behavior: 'block', reason: 'Invalid shipping country', errors: [ { message: 'Sorry, we can only ship to Canada', // Show an error underneath the country code field target: '$.cart.deliveryGroups[0].deliveryAddress.countryCode', }, { // In addition, show an error at the page level message: 'Please use a different address.', }, ], } : { behavior: 'allow', }; }, ); return ( <> {editorType === 'checkout' && !blockProgressGranted ? ( To allow this app to block checkout, enable this behavior in "Checkout behavior" settings. ) : null} ); } ``` * #### Block progress and show error at page level ##### Description Intercept and prevent a buyer's progress through checkout while displaying an error message at the page level. See the \[validation tutorial]\(/docs/apps/checkout/validation) for more examples and best practices. ##### Preact ```jsx import '@shopify/ui-extensions/preact'; import {render} from 'preact'; import { useBuyerJourneyIntercept, useExtensionEditor, useExtensionCapability, } from '@shopify/ui-extensions/checkout/preact'; export default function extension() { render(, document.body); } function Extension() { const editorType = useExtensionEditor()?.type; const blockProgressGranted = useExtensionCapability('block_progress'); useBuyerJourneyIntercept( ({canBlockProgress}) => { return canBlockProgress && shopify.shippingAddress.value ?.countryCode && shopify.shippingAddress.value .countryCode !== 'CA' ? { behavior: 'block', reason: 'Invalid shipping country', errors: [ { // An error without a `target` property is shown at page level message: 'Sorry, we can only ship to Canada', }, ], } : { behavior: 'allow', }; }, ); return ( <> {editorType === 'checkout' && !blockProgressGranted ? ( To allow this app to block checkout, enable this behavior in "Checkout behavior" settings. ) : null} ); } ``` * #### Block progress and show error in your extension ##### Description Intercept and prevent a buyer's progress through checkout while displaying an error message in your extension. See the \[validation tutorial]\(/docs/apps/checkout/validation) for more examples and best practices. ##### Preact ```jsx import '@shopify/ui-extensions/preact'; import {render} from 'preact'; import {useState} from 'preact/hooks'; import { useBuyerJourneyIntercept, useExtensionEditor, useExtensionCapability, } from '@shopify/ui-extensions/checkout/preact'; export default function extension() { render(, document.body); } function Extension() { const [showError, setShowError] = useState(false); const editorType = useExtensionEditor()?.type; const blockProgressGranted = useExtensionCapability('block_progress'); useBuyerJourneyIntercept( ({canBlockProgress}) => { return canBlockProgress && shopify.target.value.quantity > 1 ? { behavior: 'block', reason: 'limited stock', perform: (result) => { if (result.behavior === 'block') { setShowError(true); } }, } : { behavior: 'allow', perform: () => { setShowError(false); }, }; }, ); return ( <> {editorType === 'checkout' && !blockProgressGranted ? ( To allow this app to block checkout, enable this behavior in "Checkout behavior" settings. ) : null} {showError ? ( This item has a limit of one per customer. ) : null} ); } ``` ## Related [Tutorial - Validating fields at checkout](https://shopify.dev/docs/apps/checkout/validation/fields) [Reference - Targets](https://shopify.dev/docs/api/checkout-ui-extensions/targets) [Reference - Components](https://shopify.dev/docs/api/checkout-ui-extensions/components) [Reference - Configuration](https://shopify.dev/docs/api/checkout-ui-extensions/configuration) [Learn - Tutorials](https://shopify.dev/apps/checkout)