---
title: Customize the header that displays at checkout
description: Learn how to customize the checkout header with checkout UI extensions.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/checkout/customize-header?extension=polaris
  md: >-
    https://shopify.dev/docs/apps/build/checkout/customize-header.md?extension=polaris
---

# Customize the header that displays at checkout

You can customize the checkout header for custom navigation experiences. For example, you can hide the default cart link and add custom breadcrumbs.

This guide explains how to customize the header using checkout UI extensions and the checkout and accounts editor to render a customized header on the **Checkout** page.

Learn from an end-to-end example in this guide, and then explore the API documentation to suit your customization needs.

**Shopify Plus:**

Checkout UI extensions and styling customizations are available only to [Shopify Plus](https://www.shopify.com/plus) merchants.

## What you'll learn

In this tutorial, you'll learn how to do the following tasks:

* Hide the default cart link and buyer journey breadcrumbs.
* Configure a checkout UI extension for a single target to render in the header.
* Add custom breadcrumbs to the header.
* Deploy your UI extension to Shopify.

## Requirements

[The store that you're modifying with branding must be on a Shopify Plus plan.](https://help.shopify.com/manual/intro-to-shopify/pricing-plans/plans-features/shopify-plan)

* You're a [user with app development permissions](https://shopify.dev/docs/apps/build/dev-dashboard/user-permissions).

* You've created a new [development store](https://shopify.dev/docs/api/development-stores) with [test data generated by Shopify](https://shopify.dev/docs/api/development-stores/generated-test-data).

* You've [created an app](https://shopify.dev/docs/apps/build/scaffold-app) that uses Shopify CLI 3.85.1 or higher.

## Project

[View on GitHub](https://github.com/Shopify/example-checkout--custom-header--preact)

### Hide the default cart link and buyer journey breadcrumbs

In the checkout and accounts editor, you can hide the cart link and/or buyer journey breadcrumbs. In a later step, you'll replace these default elements with your own customized breadcrumbs.

### Create a checkout UI extension

To create a checkout UI extension, use Shopify CLI, which generates starter code for building your extension.

To create a checkout UI extension, you can use Shopify CLI, which generates starter code for building your extension and automates common development tasks.

1. Navigate to your app directory:

   ## Terminal

   ```terminal
   cd <directory>
   ```

2. Run the following command to create a new checkout UI extension:

   ## Terminal

   ```terminal
   shopify app generate extension --template checkout_ui --name my-checkout-ui-extension
   ```

3. Select `Checkout UI`.

   You should now have a new extension directory in your app's directory. The extension directory includes the extension script at `src/Checkout.jsx`. The following is an example directory structure:

   ## Checkout UI extension file structure

   ```text
   └── my-app
     └── extensions
       └── my-checkout-ui-extension
           ├── src
           │   └── Checkout.jsx OR Checkout.js // The index page of the checkout UI extension
           ├── locales
           │   ├── en.default.json // The default locale for the checkout UI extension
           │   └── fr.json // The locale file for non-regional French translations
           ├── shopify.extension.toml // The config file for the checkout UI extension
           └── package.json
   ```

4. Start your development server to build and preview your app:

   ## Terminal

   ```terminal
   shopify app dev
   ```

   [Read more](https://shopify.dev/docs/apps/build/cli-for-apps/test-apps-locally#overview-of-app-dev) about the processes that are executed when you run `app dev`.

5. Press `p` to open the Dev Console.

6. In the extension list for your app, click on the preview link for your extension.

### Set up the target for your extension

[Targets](https://shopify.dev/docs/api/checkout-ui-extensions/latest/targets) control where your extension renders in the checkout flow.

This example uses [purchase.checkout.header.render-after](https://shopify.dev/docs/api/checkout-ui-extensions/latest/targets).

**Note:**

There is a corresponding [purchase.thank-you.header.render-after](https://shopify.dev/docs/api/checkout-ui-extensions/latest/targets) target on the **Thank you** page. While this breadcrumbs example only renders in the **Checkout**, other use cases could benefit from targeting both **Checkout** and **Thank you** pages.

#### Reference the extension targets in your configuration file

You can define more than one target so that app users can add the extension to multiple locations in the checkout.

In your checkout UI extension's configuration file, for each of your targets, create an `[[extensions.targeting]]` section with the following information:

* `module`: The path to the file that contains the extension code.

* `target`: An identifier that specifies where you're injecting code into Shopify.

***

[`shopify.extension.toml`](https://shopify.dev/docs/apps/build/app-extensions/configure-app-extensions) is the configuration file for your extension. It contains basic information and settings.

**Note:**

Whenever you edit your extension configuration file, you need to restart your server for the changes to take effect.

## Terminal

```bash
shopify app dev
```

## /extensions/custom-breadcrumbs/shopify.extension.toml

```toml
# Learn more about configuring your checkout UI extension:
# https://shopify.dev/api/checkout-extensions/checkout/configuration


# The version of APIs your extension will receive. Learn more:
# https://shopify.dev/docs/api/usage/versioning
api_version = "2025-10"


[[extensions]]
name = "custom-breadcrumbs"
handle = "custom-breadcrumbs"
uid = "ac1cf083-1ce5-1316-e59c-41e892fd7106418f8ac4"
type = "ui_extension"




# Controls where in Shopify your extension will be injected,
# and the file that contains your extension’s source code. Learn more:
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/extension-targets-overview


[[extensions.targeting]]
module = "./src/Checkout.jsx"
target = "purchase.checkout.header.render-after"


[extensions.capabilities]
# Gives your extension access to directly query Shopify’s storefront API.
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/configuration#api-access
api_access = true
```

### Render the custom breadcrumb

In this step you'll populate the header with custom breadcrumb navigation.

#### Add custom translations for strings

Add custom translations for your "cart" string.

To better support buyers in different locales, you should avoid using hard-coded strings in your extensions. The translated `cart` string is used in line 17 of `Checkout.jsx`.

***

[Localization](https://shopify.dev/docs/apps/build/checkout/localized-checkout-ui-extensions)

#### Get the appropriate state to populate your breadcrumbs

As the buyer steps through a checkout, their `activeStep` will update to reflect where they are currently in the buyer journey. You may want to provide different treatments for visited `steps`, the `activeStep`, and `steps` in the future.

***

**Note:**

`steps` can vary between store setups, such as stores with one-page versus three-page checkout. They can also vary between buyers, such as those purchasing digital-only goods where a "Shipping" step may be omitted.

## /extensions/custom-breadcrumbs/src/Checkout.jsx

```jsx
import '@shopify/ui-extensions/preact';
import {render} from "preact";


export default function() {
  render(<Extension />, document.body)
}


function Extension() {
  const {
    i18n,
    buyerJourney: {steps, activeStep},
    shop: {storefrontUrl}
  } = shopify;


  const assembledSteps = [
    {
      label: i18n.translate('cart'),
      handle: 'cart',
      to: new URL('/cart', storefrontUrl).href,
    },
    ...steps?.current ?? [],
  ];


  const activeStepIndex = assembledSteps.findIndex(
    ({handle}) => handle === activeStep?.current?.handle,
  );


  const columns = `repeat(${assembledSteps.length}, 1fr)`


  return (
    <s-grid
      accessibilityRole="ordered-list"
      border="base base solid"
      borderRadius="base"
      gridTemplateColumns={columns}
    >
      {assembledSteps.map(({label, handle, to}, index) => (
        <s-grid
          accessibilityRole="list-item"
          background={index === activeStepIndex ? 'subdued' : 'transparent'}
          borderStyle={index === assembledSteps.length - 1 ? "none" : "none solid none none"}
          borderWidth="base"
          justifyItems="center"
          padding="small-300"
          key={handle}
        >
          {index < activeStepIndex || handle === 'cart' ? (
            <s-link href={to}>{label}</s-link>
          ) : (
            <s-text>{label}</s-text>
          )}
        </s-grid>
      ))}
    </s-grid>
  );
}
```

#### Add custom breadcrumbs

Render custom breadcrumbs using checkout UI components and the `steps` and `activeStep` returned from the buyer journey hooks.

***

[Link](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/link) [Text](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/typography-and-content/text) [Grid](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/layout-and-structure/grid)

## /extensions/custom-breadcrumbs/src/Checkout.jsx

```jsx
import '@shopify/ui-extensions/preact';
import {render} from "preact";


export default function() {
  render(<Extension />, document.body)
}


function Extension() {
  const {
    i18n,
    buyerJourney: {steps, activeStep},
    shop: {storefrontUrl}
  } = shopify;


  const assembledSteps = [
    {
      label: i18n.translate('cart'),
      handle: 'cart',
      to: new URL('/cart', storefrontUrl).href,
    },
    ...steps?.current ?? [],
  ];


  const activeStepIndex = assembledSteps.findIndex(
    ({handle}) => handle === activeStep?.current?.handle,
  );


  const columns = `repeat(${assembledSteps.length}, 1fr)`


  return (
    <s-grid
      accessibilityRole="ordered-list"
      border="base base solid"
      borderRadius="base"
      gridTemplateColumns={columns}
    >
      {assembledSteps.map(({label, handle, to}, index) => (
        <s-grid
          accessibilityRole="list-item"
          background={index === activeStepIndex ? 'subdued' : 'transparent'}
          borderStyle={index === assembledSteps.length - 1 ? "none" : "none solid none none"}
          borderWidth="base"
          justifyItems="center"
          padding="small-300"
          key={handle}
        >
          {index < activeStepIndex || handle === 'cart' ? (
            <s-link href={to}>{label}</s-link>
          ) : (
            <s-text>{label}</s-text>
          )}
        </s-grid>
      ))}
    </s-grid>
  );
}
```

### Preview the extension

Preview your extension to make sure that it works as expected.

#### Start your server

Run the Shopify CLI `dev` command to build your app and preview it on your development store.

1. In a terminal, navigate to your app directory.

2. Either start or restart your server to build and preview your app:

   ## Terminal

   ```bash
   shopify app dev
   ```

3. Press `p` to open the Dev Console.

4. In the extension list for your app, click on the preview link for the custom header extension.

   The checkout opens.

***

This section describes how to solve some potential errors when you run `dev` for an app that contains a checkout UI extension.

### Property token error

If you receive the error `ShopifyCLI:AdminAPI requires the property token to be set`, then you'll need to use the [`--checkout-cart-url` flag](https://shopify.dev/docs/api/shopify-cli/app/app-dev#flags) to direct Shopify CLI to open a checkout session for you.

## Terminal

```terminal
shopify app dev --checkout-cart-url cart/{product_variant_id}:{quantity}
```

### Missing checkout link

If you don't receive the test checkout URL when you run `dev`, then verify the following:

* You have a development store populated with products.

* You're logged in to the correct Partners organization and development store. To verify, check your app info using the following command:

  ## Terminal

  ```terminal
  shopify app info
  ```

Otherwise, you can manually create a checkout with the following steps:

1. From your development store's storefront, add some products to your cart.

2. From the cart, click **Checkout**.

3. From directory of the app that contains your extension, run `dev` to preview your app:

   ## Terminal

   ```terminal
   shopify app dev
   ```

4. On the checkout page for your store, change the URL by appending the `?dev=https://{tunnel_url}/extensions` query string and reload the page. The `tunnel_url` parameter allows your app to be accessed using a unique HTTPS URL.

   You should now see a rendered order note that corresponds to the code in your project template.

When you're ready to release your changes to users, you can create and release an [app version](https://shopify.dev/docs/apps/launch/deployment/app-versions). An app version is a snapshot of your app configuration and all extensions.

1. Navigate to your app directory.

2. Run the following command.

   Optionally, you can provide a name or message for the version using the `--version` and `--message` flags.

   ## Terminal

   ```terminal
   shopify app deploy
   ```

Releasing an app version replaces the current active version that's served to stores that have your app installed. It might take several minutes for app users to be upgraded to the new version.

**Tip:**

If you want to create a version, but avoid releasing it to users, then run the `deploy` command with a `--no-release` flag. You can release the unreleased app version using Shopify CLI's [`release`](https://shopify.dev/docs/api/shopify-cli/app/app-release) command, or through the Dev Dashboard.

## /extensions/custom-breadcrumbs/shopify.extension.toml

```toml
# Learn more about configuring your checkout UI extension:
# https://shopify.dev/api/checkout-extensions/checkout/configuration


# The version of APIs your extension will receive. Learn more:
# https://shopify.dev/docs/api/usage/versioning
api_version = "2025-10"


[[extensions]]
name = "custom-breadcrumbs"
handle = "custom-breadcrumbs"
uid = "ac1cf083-1ce5-1316-e59c-41e892fd7106418f8ac4"
type = "ui_extension"




# Controls where in Shopify your extension will be injected,
# and the file that contains your extension’s source code. Learn more:
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/extension-targets-overview


[[extensions.targeting]]
module = "./src/Checkout.jsx"
target = "purchase.checkout.header.render-after"


[extensions.capabilities]
# Gives your extension access to directly query Shopify’s storefront API.
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/configuration#api-access
api_access = true
```

## /extensions/custom-breadcrumbs/locales/en.default.json

```json
{
  "cart": "My Cart"
}
```

## /extensions/custom-breadcrumbs/src/Checkout.jsx

```jsx
import '@shopify/ui-extensions/preact';
import {render} from "preact";


export default function() {
  render(<Extension />, document.body)
}


function Extension() {
  const {
    i18n,
    buyerJourney: {steps, activeStep},
    shop: {storefrontUrl}
  } = shopify;


  const assembledSteps = [
    {
      label: i18n.translate('cart'),
      handle: 'cart',
      to: new URL('/cart', storefrontUrl).href,
    },
    ...steps?.current ?? [],
  ];


  const activeStepIndex = assembledSteps.findIndex(
    ({handle}) => handle === activeStep?.current?.handle,
  );


  const columns = `repeat(${assembledSteps.length}, 1fr)`


  return (
    <s-grid
      accessibilityRole="ordered-list"
      border="base base solid"
      borderRadius="base"
      gridTemplateColumns={columns}
    >
      {assembledSteps.map(({label, handle, to}, index) => (
        <s-grid
          accessibilityRole="list-item"
          background={index === activeStepIndex ? 'subdued' : 'transparent'}
          borderStyle={index === assembledSteps.length - 1 ? "none" : "none solid none none"}
          borderWidth="base"
          justifyItems="center"
          padding="small-300"
          key={handle}
        >
          {index < activeStepIndex || handle === 'cart' ? (
            <s-link href={to}>{label}</s-link>
          ) : (
            <s-text>{label}</s-text>
          )}
        </s-grid>
      ))}
    </s-grid>
  );
}
```

## Tutorial complete!

Nice work - what you just built could be used by Shopify merchants around the world! Keep the momentum going with these related tutorials and resources.

### Next steps

[Localize your extension\
\
](https://shopify.dev/docs/apps/checkout/localizing-ui-extensions)

[Learn how to localize the text and number formats in your extension.](https://shopify.dev/docs/apps/checkout/localizing-ui-extensions)

[Explore the checkout UI extension component reference\
\
](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components)

[Learn about all the components you can use in your checkout UI extensions.](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components)

[Explore the checkout branding API\
\
](https://shopify.dev/docs/apps/checkout/styling)

[Learn about other properties that are exposed in the GraphQL Admin API's checkout branding types.](https://shopify.dev/docs/apps/checkout/styling)
