---
title: Build new pages in customer accounts
description: >-
  Learn how to build a full-page extension for customer wishlists, using
  customer account UI extensions.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/customer-accounts/full-page-extensions/build-new-pages
  md: >-
    https://shopify.dev/docs/apps/build/customer-accounts/full-page-extensions/build-new-pages.md
api_name: customer-account-ui-extensions
---

# Build new pages in customer accounts

Full-page UI extensions enable you to create a page within the customer account experience while preserving a merchant's branding.

In this tutorial, you'll learn how to create a standalone full-page UI extension that customers can access without leaving their account or needing to log in again.

## What you'll learn

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

* Create a full-page UI extension in customer accounts
* Create a full-page extension entry point to test your full-page extension
* Use web components like [page](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/web-components/layout-and-structure/page) and [section](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/web-components/layout-and-structure/section) to build a page for customer wishlists
* Query the [Storefront API](https://shopify.dev/docs/api/storefront) to retrieve a list of products
* Navigate to your full-page extension
* Run the extension locally and test it on a dev store

## Requirements

[Create a Partner account](https://www.shopify.com/partners)

[Create a development store](https://shopify.dev/docs/apps/build/stores/development-stores)

The development store should be pre-populated with [test data](https://shopify.dev/docs/apps/build/stores/generated-test-data), including an order associated with the email address you'll use to log in to the customer account experience.

[Shopify CLI](https://shopify.dev/docs/apps/tools/cli/installation)

You'll need to use the [latest version of Shopify CLI](https://shopify.dev/docs/api/shopify-cli#upgrade).

[Scaffold an app](https://shopify.dev/docs/apps/build/scaffold-app)

Scaffold an app that uses Shopify CLI.

## Project

[View on GitHub](https://github.com/Shopify/customer-account-tutorials/tree/main/preact/example-customer-account--wishlist--preact)

### Create a customer account UI extension for the full-page target

To create a customer account 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 customer account UI extension:

   ## Terminal

   ```terminal
   shopify app generate extension --template customer_account_ui --name customer-account-ui-extension
   ```

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

   ## Customer account UI extension file structure

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

1) Start your development server to build and preview your app:

   ## Terminal

   ```terminal
   shopify app dev
   ```

   To learn about the processes that are executed when you run `dev`, refer to the [Shopify CLI command reference](https://shopify.dev/docs/api/shopify-cli/app/app-dev).

2) Press `p` to open the Dev Console.

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

### Set up the target for your full-page extension

Set up the targets for your customer account UI extension. [Targets](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/targets) control where your extension renders in the account. A full-page target cannot coexist with any other targets in the same extension.

In this example, you'll create a page that lists products in the customer's wishlist, and a link to that page.

#### Reference the targets in your configuration file

This example code uses the `customer-account.page.render` target.

In your extension's [`shopify.extension.toml`](https://shopify.dev/docs/apps/build/app-extensions/configure-app-extensions) configuration file, for each of the targets, create an `[[extensions.targeting]]` section with the following information:

* **`target`**: An identifier that specifies where you're injecting code into Shopify.
* **`module`**: The path to the file that contains the extension code.

***

[customer-account.page.render](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/targets/full-page#customer-account-full-page-)

## /preact/example-customer-account--wishlist--preact/extensions/customer-account-wishlist-extension/shopify.extension.toml

```toml
api_version = "2025-10"


[[extensions]]
uid = "3a495b4c-7432-f824-50b6-44ec8381c25e7d2a5779"
type = "ui_extension"
name = "My wishlist"
handle = "wishlist-extension-preact"


[[extensions.targeting]]
module = "./src/FullPageExtension.jsx"
target = "customer-account.page.render"


[extensions.capabilities]
api_access = true
```

#### Create files for your targets

Create a file in your extension's `src` directory for each of your targets. In this example, you'll create a file for the profile block extension and a file for the full-page extension. The filenames must match the `module` paths you specified.

## /preact/example-customer-account--wishlist--preact/extensions/customer-account-wishlist-extension/src/FullPageExtension.jsx

```jsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
import {useEffect, useState} from 'preact/hooks';


export default async () => {
  render(<FullPageExtension />, document.body);
};


function FullPageExtension() {
  const [wishlist, setWishlist] = useState([]);
  const [loading, setLoading] = useState(false);
  const [removeLoading, setRemoveLoading] = useState({
    id: null,
    loading: false,
  });


  async function fetchWishlist() {
    setLoading(true);


    try {
      // Implement a server request to retrieve the wishlist for this customer
      // Then call the Storefront API to retrieve the details of the wishlisted products
      const data = await shopify.query(
        `query ($first: Int!) {
          products(first: $first) {
            nodes {
              id
              title
              onlineStoreUrl
              priceRange {
                minVariantPrice {
                  amount
                  currencyCode
                }
              }
              featuredImage {
                url
              }
            }
          }
        }`,
        {
          variables: {first: 10},
        }
      );
      setLoading(false);
      setWishlist(data.data?.products?.nodes || []);
    } catch (error) {
      setLoading(false);
      console.log(error);
    }
  }


  async function deleteWishlistItem(id) {
    // Simulate a server request
    setRemoveLoading({loading: true, id});
    return new Promise((resolve) => {
      setTimeout(() => {
        // Send a request to your server to delete the wishlist item
        setWishlist(wishlist.filter((item) => item.id !== id));


        setRemoveLoading({loading: false, id: null});
        resolve();
      }, 750);
    });
  }


  useEffect(() => {
    fetchWishlist();
  }, []);


  return (
    <s-page heading="Wishlist">
      <s-grid gridTemplateColumns="1fr 1fr 1fr" gap="base">
        {!loading &&
          wishlist.length > 0 &&
          wishlist.map((product) => {
            return (
              <s-section key={product.id}>
                <s-stack direction="block" gap="base" paddingBlockEnd="large">
                  <s-image src={product.featuredImage.url} />
                  <s-stack direction="block" gap="small-500">
                    <s-text color="subdued">{product.title}</s-text>
                    <s-text type="strong">
                      {shopify.i18n.formatCurrency(
                        product.priceRange.minVariantPrice.amount,
                        {
                          currency:
                            product.priceRange.minVariantPrice.currencyCode,
                        }
                      )}
                    </s-text>
                  </s-stack>
                </s-stack>
                <s-button slot="primary-action" href={product.onlineStoreUrl}>
                  View product
                </s-button>
                <s-button
                  slot="secondary-actions"
                  loading={
                    removeLoading.loading && product.id === removeLoading.id
                  }
                  onClick={() => {
                    deleteWishlistItem(product.id);
                  }}
                >
                  Remove
                </s-button>
              </s-section>
            );
          })}
        {!loading && wishlist.length === 0 && (
          <s-text>No items in your wishlist.</s-text>
        )}
      </s-grid>
    </s-page>
  );
}
```

### Create a customer account UI extension for the full-page entry point for testing

Create an extension, to define an entry point to the full-page extension created above.

To create a customer account 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 customer account UI extension:

   ## Terminal

   ```terminal
   shopify app generate extension --template customer_account_ui --name customer-account-ui-extension
   ```

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

   ## Customer account UI extension file structure

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

1) Start your development server to build and preview your app:

   ## Terminal

   ```terminal
   shopify app dev
   ```

   To learn about the processes that are executed when you run `dev`, refer to the [Shopify CLI command reference](https://shopify.dev/docs/api/shopify-cli/app/app-dev).

2) Press `p` to open the Dev Console.

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

### Set up the target for your entry point

Set up the target for your customer account UI extension. [Targets](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/targets) control where your extension renders in the customer account flow.

The example code uses the `customer-account.profile.block.render` target

#### Add the `customer-account.profile.block.render` target to your configuration file

In your extension's configuration file, for the `customer-account.profile.block.render` target, create an `[[extensions.targeting]]` section with the following information:

**`target`**: An identifier that specifies where you're injecting code into Shopify. **`module`**: The path to the file that contains the extension code.

## /preact/example-customer-account--wishlist--preact/extensions/wishlist-profile-block/shopify.extension.toml

```toml
api_version = "2025-10"


[[extensions]]
uid = "a1eb23c4-ce29-1e17-8061-132bf7a545b9d9bca54d"
type = "ui_extension"
name = "Upsell banner"
handle = "wishlist-profile-block"


[[extensions.targeting]]
module = "./src/ProfileBlockExtension.jsx"
target = "customer-account.profile.block.render"


[extensions.capabilities]
api_access = true
```

#### Create files for your targets

Create a file in your extension's `src` directory for the target. In this example, you'll create a file for the profile block extension. Make sure that the name of the files match the `module` paths that you specified.

[shopify.extension.toml](https://shopify.dev/docs/apps/build/app-extensions/configure-app-extensions) is the configuration file for your extension.

***

[customer-account.profile.block.render](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/targets/profile-page-default#profile-block-)

## /preact/example-customer-account--wishlist--preact/extensions/wishlist-profile-block/src/ProfileBlockExtension.jsx

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


export default async () => {
  render(<BlockExtension />, document.body);
};


function BlockExtension() {
  return (
    <s-section>
      <s-stack
        direction="inline"
        justifyContent="space-between"
        alignItems="center"
      >
        <s-stack direction="block" gap="small-400">
          <s-heading>My Wishlist</s-heading>
          <s-text>
            View your favorites and save new looks in your wishlist collections.
          </s-text>
        </s-stack>
        <s-button variant="primary" href="extension:wishlist-extension-preact/">
          View wishlist
        </s-button>
      </s-stack>
    </s-section>
  );
}
```

### Build the full-page extension

#### Fetch the customer's wishlist

Create an asynchronous function to fetch the wishlist from your server, and invoke it within a side effect.

In this example, you'll retrieve the shop's first ten products from the [Storefront API](https://shopify.dev/docs/api/storefront). In a production-ready application, first retrieve the customer's wishlist from your server, and then retrieve the product details from the Storefront API.

## /preact/example-customer-account--wishlist--preact/extensions/customer-account-wishlist-extension/src/FullPageExtension.jsx

```jsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
import {useEffect, useState} from 'preact/hooks';


export default async () => {
  render(<FullPageExtension />, document.body);
};


function FullPageExtension() {
  const [wishlist, setWishlist] = useState([]);
  const [loading, setLoading] = useState(false);
  const [removeLoading, setRemoveLoading] = useState({
    id: null,
    loading: false,
  });


  async function fetchWishlist() {
    setLoading(true);


    try {
      // Implement a server request to retrieve the wishlist for this customer
      // Then call the Storefront API to retrieve the details of the wishlisted products
      const data = await shopify.query(
        `query ($first: Int!) {
          products(first: $first) {
            nodes {
              id
              title
              onlineStoreUrl
              priceRange {
                minVariantPrice {
                  amount
                  currencyCode
                }
              }
              featuredImage {
                url
              }
            }
          }
        }`,
        {
          variables: {first: 10},
        }
      );
      setLoading(false);
      setWishlist(data.data?.products?.nodes || []);
    } catch (error) {
      setLoading(false);
      console.log(error);
    }
  }


  async function deleteWishlistItem(id) {
    // Simulate a server request
    setRemoveLoading({loading: true, id});
    return new Promise((resolve) => {
      setTimeout(() => {
        // Send a request to your server to delete the wishlist item
        setWishlist(wishlist.filter((item) => item.id !== id));


        setRemoveLoading({loading: false, id: null});
        resolve();
      }, 750);
    });
  }


  useEffect(() => {
    fetchWishlist();
  }, []);


  return (
    <s-page heading="Wishlist">
      <s-grid gridTemplateColumns="1fr 1fr 1fr" gap="base">
        {!loading &&
          wishlist.length > 0 &&
          wishlist.map((product) => {
            return (
              <s-section key={product.id}>
                <s-stack direction="block" gap="base" paddingBlockEnd="large">
                  <s-image src={product.featuredImage.url} />
                  <s-stack direction="block" gap="small-500">
                    <s-text color="subdued">{product.title}</s-text>
                    <s-text type="strong">
                      {shopify.i18n.formatCurrency(
                        product.priceRange.minVariantPrice.amount,
                        {
                          currency:
                            product.priceRange.minVariantPrice.currencyCode,
                        }
                      )}
                    </s-text>
                  </s-stack>
                </s-stack>
                <s-button slot="primary-action" href={product.onlineStoreUrl}>
                  View product
                </s-button>
                <s-button
                  slot="secondary-actions"
                  loading={
                    removeLoading.loading && product.id === removeLoading.id
                  }
                  onClick={() => {
                    deleteWishlistItem(product.id);
                  }}
                >
                  Remove
                </s-button>
              </s-section>
            );
          })}
        {!loading && wishlist.length === 0 && (
          <s-text>No items in your wishlist.</s-text>
        )}
      </s-grid>
    </s-page>
  );
}
```

#### Build the page UI

In your full-page extension file, create a function to set up the page UI. To match the look and feel of the customer accounts experience, use the page and section components.

***

![A preview of the wishlist full-page extension UI, built with page and section components.](https://shopify.dev/assets/assets/images/apps/customer-accounts/full-page-extensions/build-the-page-ui-ChZ2t78V.png)

Customer account UI extensions are limited to specific UI components exposed by the platform [for security reasons](https://shopify.dev/docs/api/customer-account-ui-extensions#security). You can use checkout UI components and customer account UI components to create a UI that feels seamless within the customer accounts experience, and that inherits a merchant's brand settings.

[Page](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/web-components/layout-and-structure/page) [Grid](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/layout-and-structure/grid) [Section](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/web-components/layout-and-structure/section) [Image](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/media-and-visuals/image) [Stack](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/layout-and-structure/stack) [Text](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/typography-and-content/text) [Button](https://shopify.dev/docs/api/checkout-ui-extensions/latest/web-components/actions/button)

## /preact/example-customer-account--wishlist--preact/extensions/customer-account-wishlist-extension/src/FullPageExtension.jsx

```jsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
import {useEffect, useState} from 'preact/hooks';


export default async () => {
  render(<FullPageExtension />, document.body);
};


function FullPageExtension() {
  const [wishlist, setWishlist] = useState([]);
  const [loading, setLoading] = useState(false);
  const [removeLoading, setRemoveLoading] = useState({
    id: null,
    loading: false,
  });


  async function fetchWishlist() {
    setLoading(true);


    try {
      // Implement a server request to retrieve the wishlist for this customer
      // Then call the Storefront API to retrieve the details of the wishlisted products
      const data = await shopify.query(
        `query ($first: Int!) {
          products(first: $first) {
            nodes {
              id
              title
              onlineStoreUrl
              priceRange {
                minVariantPrice {
                  amount
                  currencyCode
                }
              }
              featuredImage {
                url
              }
            }
          }
        }`,
        {
          variables: {first: 10},
        }
      );
      setLoading(false);
      setWishlist(data.data?.products?.nodes || []);
    } catch (error) {
      setLoading(false);
      console.log(error);
    }
  }


  async function deleteWishlistItem(id) {
    // Simulate a server request
    setRemoveLoading({loading: true, id});
    return new Promise((resolve) => {
      setTimeout(() => {
        // Send a request to your server to delete the wishlist item
        setWishlist(wishlist.filter((item) => item.id !== id));


        setRemoveLoading({loading: false, id: null});
        resolve();
      }, 750);
    });
  }


  useEffect(() => {
    fetchWishlist();
  }, []);


  return (
    <s-page heading="Wishlist">
      <s-grid gridTemplateColumns="1fr 1fr 1fr" gap="base">
        {!loading &&
          wishlist.length > 0 &&
          wishlist.map((product) => {
            return (
              <s-section key={product.id}>
                <s-stack direction="block" gap="base" paddingBlockEnd="large">
                  <s-image src={product.featuredImage.url} />
                  <s-stack direction="block" gap="small-500">
                    <s-text color="subdued">{product.title}</s-text>
                    <s-text type="strong">
                      {shopify.i18n.formatCurrency(
                        product.priceRange.minVariantPrice.amount,
                        {
                          currency:
                            product.priceRange.minVariantPrice.currencyCode,
                        }
                      )}
                    </s-text>
                  </s-stack>
                </s-stack>
                <s-button slot="primary-action" href={product.onlineStoreUrl}>
                  View product
                </s-button>
                <s-button
                  slot="secondary-actions"
                  loading={
                    removeLoading.loading && product.id === removeLoading.id
                  }
                  onClick={() => {
                    deleteWishlistItem(product.id);
                  }}
                >
                  Remove
                </s-button>
              </s-section>
            );
          })}
        {!loading && wishlist.length === 0 && (
          <s-text>No items in your wishlist.</s-text>
        )}
      </s-grid>
    </s-page>
  );
}
```

### Add a link to your full-page extension

In your profile block extension file, create a function to set up the link that routes to your full-page extension. Setting the `href` prop to `extension:wishlist-extension-preact/` instructs the router to navigate to the full-page extension that you created.

***

![A profile block extension rendering a link banner that routes to the wishlist full-page extension.](https://shopify.dev/assets/assets/images/apps/customer-accounts/full-page-extensions/add-link-to-full-page-extension-DH0l8QmH.png)

When navigating to a full-page extension from another extension within the same app, use the `extension:$full-page-extension-handle/` protocol.

In a production-ready application, don't include this link in your extension. Instead, only publish the full-page extension. Merchants can add a link to it in the header navigation menu of their customer accounts experience.

[Section](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/web-components/layout-and-structure/section) [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)

## /preact/example-customer-account--wishlist--preact/extensions/wishlist-profile-block/src/ProfileBlockExtension.jsx

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


export default async () => {
  render(<BlockExtension />, document.body);
};


function BlockExtension() {
  return (
    <s-section>
      <s-stack
        direction="inline"
        justifyContent="space-between"
        alignItems="center"
      >
        <s-stack direction="block" gap="small-400">
          <s-heading>My Wishlist</s-heading>
          <s-text>
            View your favorites and save new looks in your wishlist collections.
          </s-text>
        </s-stack>
        <s-button variant="primary" href="extension:wishlist-extension-preact/">
          View wishlist
        </s-button>
      </s-stack>
    </s-section>
  );
}
```

### Preview and test 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. If prompted, select a development store.

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

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

The customer accounts experience opens.

#### Test the full-page extension

1. Navigate to the profile page by clicking the dropdown in the top right corner of the customer account and selecting **Profile**.

2. Click the **View wishlist** link in the banner that you created.

You're taken to the full-page extension you created, which lists out the products in the customer's wishlist.

***

![A preview of the wishlist full-page extension UI, built with page and section components.](https://shopify.dev/assets/assets/images/apps/customer-accounts/full-page-extensions/build-the-page-ui-ChZ2t78V.png)

## /preact/example-customer-account--wishlist--preact/extensions/customer-account-wishlist-extension/shopify.extension.toml

```toml
api_version = "2025-10"


[[extensions]]
uid = "3a495b4c-7432-f824-50b6-44ec8381c25e7d2a5779"
type = "ui_extension"
name = "My wishlist"
handle = "wishlist-extension-preact"


[[extensions.targeting]]
module = "./src/FullPageExtension.jsx"
target = "customer-account.page.render"


[extensions.capabilities]
api_access = true
```

## /preact/example-customer-account--wishlist--preact/extensions/customer-account-wishlist-extension/src/FullPageExtension.jsx

```jsx
import '@shopify/ui-extensions/preact';
import {render} from 'preact';
import {useEffect, useState} from 'preact/hooks';


export default async () => {
  render(<FullPageExtension />, document.body);
};


function FullPageExtension() {
  const [wishlist, setWishlist] = useState([]);
  const [loading, setLoading] = useState(false);
  const [removeLoading, setRemoveLoading] = useState({
    id: null,
    loading: false,
  });


  async function fetchWishlist() {
    setLoading(true);


    try {
      // Implement a server request to retrieve the wishlist for this customer
      // Then call the Storefront API to retrieve the details of the wishlisted products
      const data = await shopify.query(
        `query ($first: Int!) {
          products(first: $first) {
            nodes {
              id
              title
              onlineStoreUrl
              priceRange {
                minVariantPrice {
                  amount
                  currencyCode
                }
              }
              featuredImage {
                url
              }
            }
          }
        }`,
        {
          variables: {first: 10},
        }
      );
      setLoading(false);
      setWishlist(data.data?.products?.nodes || []);
    } catch (error) {
      setLoading(false);
      console.log(error);
    }
  }


  async function deleteWishlistItem(id) {
    // Simulate a server request
    setRemoveLoading({loading: true, id});
    return new Promise((resolve) => {
      setTimeout(() => {
        // Send a request to your server to delete the wishlist item
        setWishlist(wishlist.filter((item) => item.id !== id));


        setRemoveLoading({loading: false, id: null});
        resolve();
      }, 750);
    });
  }


  useEffect(() => {
    fetchWishlist();
  }, []);


  return (
    <s-page heading="Wishlist">
      <s-grid gridTemplateColumns="1fr 1fr 1fr" gap="base">
        {!loading &&
          wishlist.length > 0 &&
          wishlist.map((product) => {
            return (
              <s-section key={product.id}>
                <s-stack direction="block" gap="base" paddingBlockEnd="large">
                  <s-image src={product.featuredImage.url} />
                  <s-stack direction="block" gap="small-500">
                    <s-text color="subdued">{product.title}</s-text>
                    <s-text type="strong">
                      {shopify.i18n.formatCurrency(
                        product.priceRange.minVariantPrice.amount,
                        {
                          currency:
                            product.priceRange.minVariantPrice.currencyCode,
                        }
                      )}
                    </s-text>
                  </s-stack>
                </s-stack>
                <s-button slot="primary-action" href={product.onlineStoreUrl}>
                  View product
                </s-button>
                <s-button
                  slot="secondary-actions"
                  loading={
                    removeLoading.loading && product.id === removeLoading.id
                  }
                  onClick={() => {
                    deleteWishlistItem(product.id);
                  }}
                >
                  Remove
                </s-button>
              </s-section>
            );
          })}
        {!loading && wishlist.length === 0 && (
          <s-text>No items in your wishlist.</s-text>
        )}
      </s-grid>
    </s-page>
  );
}
```

## /preact/example-customer-account--wishlist--preact/extensions/wishlist-profile-block/shopify.extension.toml

```toml
api_version = "2025-10"


[[extensions]]
uid = "a1eb23c4-ce29-1e17-8061-132bf7a545b9d9bca54d"
type = "ui_extension"
name = "Upsell banner"
handle = "wishlist-profile-block"


[[extensions.targeting]]
module = "./src/ProfileBlockExtension.jsx"
target = "customer-account.profile.block.render"


[extensions.capabilities]
api_access = true
```

## /preact/example-customer-account--wishlist--preact/extensions/wishlist-profile-block/src/ProfileBlockExtension.jsx

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


export default async () => {
  render(<BlockExtension />, document.body);
};


function BlockExtension() {
  return (
    <s-section>
      <s-stack
        direction="inline"
        justifyContent="space-between"
        alignItems="center"
      >
        <s-stack direction="block" gap="small-400">
          <s-heading>My Wishlist</s-heading>
          <s-text>
            View your favorites and save new looks in your wishlist collections.
          </s-text>
        </s-stack>
        <s-button variant="primary" href="extension:wishlist-extension-preact/">
          View wishlist
        </s-button>
      </s-stack>
    </s-section>
  );
}
```

## 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

[Extension placement\
\
](https://shopify.dev/docs/apps/customer-accounts/best-practices/deciding-extension-placement)

[Explore extension placement options and make informed decisions on where to position them.](https://shopify.dev/docs/apps/customer-accounts/best-practices/deciding-extension-placement)

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

[Learn about localizing your customer account UI extensions for international merchants and customers.](https://shopify.dev/docs/apps/customer-accounts/best-practices/localizing-ui-extensions)

[Targets\
\
](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/targets)

[Learn about the targets offered for customer accounts.](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/targets)

[UX guidelines\
\
](https://shopify.dev/docs/apps/customer-accounts/best-practices/ux-guidelines)

[Follow our UX guidelines for customer accounts to ensure a consistent and satisfying user experience.](https://shopify.dev/docs/apps/customer-accounts/best-practices/ux-guidelines)

[Web components\
\
](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/web-components)

[Learn about the components you can use to build customer account UI extensions.](https://shopify.dev/docs/api/customer-account-ui-extensions/latest/web-components)

[Editor extension collections\
\
](https://shopify.dev/docs/apps/build/customer-accounts/editor-extension-collections)

[Learn how to create editor extension collections to group related extensions.](https://shopify.dev/docs/apps/build/customer-accounts/editor-extension-collections)
