Adding Custom Features to Shopify's New Customer Account Pages: What UI Extensions Can and Can't Do
The observed behavior in this article was verified in August 2026 by building an extension on a test store with Shopify CLI 3.90 and api_version 2026-04. Where a behavior is specified in the official documentation, we link to it; behavior not covered by the documentation is marked as something we confirmed on a test store.
Introduction: Adding That One Missing Feature to the New Account Pages
On stores that have switched to new customer accounts, requests start to come in: show a membership tier, display the customization details of past orders, add a button that reorders just one item rather than the whole order, or surface data held in an external system. Each looks like a small addition to the standard account pages, but the new account pages are a Shopify-hosted UI that the theme cannot touch.
With legacy accounts, you could build out the account pages by editing the theme's templates/customers/*.liquid. New customer accounts don't use those templates, and there is simply no way to build the account pages in theme code. Instead, the mechanism for apps to inject their own UI has been consolidated into Customer Account UI Extensions (UIE for short).
After reading the official documentation and building an extension on a test store, we found that beyond what UIE can and can't do, there is a third category: things that are possible on paper but need care on a real store. The implementation steps are covered in the following four articles.
- Getting Started with Customer Account UI Extensions: From Scaffold to Testing on a Live Store [Tutorial]
- Reading and Writing Past Order Data with Customer Account UI Extensions: When to Use Signals, GraphQL, and Metafields [Tutorial]
- Adding a “Reorder Just This Item” Button to Shopify Customer Accounts: Cart Permalinks and Navigation Constraints [Tutorial]
- Calling External APIs from Customer Account UI Extensions: network_access, CORS, and Testing with Real Data [Tutorial] This article is written for developers about to extend the account pages; the migration steps and schedule themselves are covered separately in the migration guide. Legacy customer accounts have been officially deprecated and can no longer be selected for new stores. Anything you build from here on will be built on the assumption of new customer accounts.
1. What UIE Can Do, Can't Do, and Where It Needs Care in Practice
Sorting UIE capabilities into just two buckets, "possible per the official spec" and "not possible per the official spec," isn't enough to design with. Between the two sits a third category: things the spec allows but that need care on a real store. Design from the reference alone, and this is where the rework happens.
In the table, "official" marks items documented in the official documentation; "verified" and "confirmed" mark behavior not covered by the documentation that we confirmed on a test store in August 2026. The signal is the data an extension receives through the shopify.* globals; we explain it in Section 2.
| Category | Item | Notes |
|---|---|---|
| ✅ Can do | Display line item properties from past orders | Readable from the signal. Properties starting with _ aren't hidden either (verified). Reading and writing past order data |
| ✅ Can do | Read and write customer and order metafields | Reading requires a declaration in the toml and an access setting; writing uses metafieldsSet (official). Reading and writing past order data |
| ✅ Can do | Add products to the cart | Pass the products in a cart permalink URL (official). "Reorder just this item" button |
| ✅ Can do | Call external APIs directly | Possible once the network_access setting and the CORS conditions are met (official). Calling external APIs |
| ✅ Can do | Add new pages | Done with a full-page extension plus a menu item (official) |
| ⚠️ Caution | Line item properties with empty values | Missing from the signal (verified; not documented). Reading and writing past order data |
| ⚠️ Caution | Order customAttributes | Not in the GraphQL schema, but available from the signal (confirmed). Reading and writing past order data |
| ⚠️ Caution | Modals within a single extension | Limited to one. Place more than one and the blocks that follow silently disappear (verified). Reading and writing past order data |
| ⚠️ Caution | Bundle size | Capped at 64 KB compressed, enforced at deploy time (official). Getting started |
| ⚠️ Caution | Full-page targets | Can't coexist with other targets; the extension has to be split (official). Getting started |
| ❌ Can't do | Programmatic navigation to the storefront or external URLs | The official docs explicitly state that the Navigation API works only within the account. Navigate outward with href. "Reorder just this item" button |
| ❌ Can't do | Direct cart API manipulation | There is no equivalent of the checkout extension's applyCartLinesChange. "Reorder just this item" button |
| ❌ Can't do | Adding selling plan (subscription) products via permalink | An official constraint, and confirmed on a real store as well. "Reorder just this item" button |
| ❌ Can't do | Arbitrary HTML/CSS | The UI is limited to Polaris Web Components (official) |
The rest of this article explains, in order, the reasons behind each constraint in the table and how to implement with those constraints in mind.
2. An Overview of Customer Account UI Extensions
Building Blocks: Targets, Target APIs, and Web Components
Injecting UI into the account pages combines three things: where to inject it, what data is available at that location, and how to render the screen. The official reference calls these targets, target APIs, and web components, respectively. The locations where targets can be injected are predefined. The data available differs by injection point and is received through the target APIs. Data arrives through two channels: the signal received from the shopify.* globals, and the Customer Account API. Web components are the rendering layer; you build the screen by combining Polaris Web Components such as <s-text> and <s-button>.
The implementation is Preact-based, and the code you write is hosted by Shopify. It runs in a sandboxed Web Worker, an isolated environment, so it can't manipulate the page's DOM directly. This isolated execution environment is the single biggest difference from the days of editing theme code.
The Main Catalog of Injection Points (Targets)
Every available location is listed in the target list. The table below pulls out the commonly used ones and is not exhaustive.
| Location | Representative target | Purpose |
|---|---|---|
| Order index | customer-account.order-index.block.render |
Adds information to the order list |
| Order details | customer-account.order-status.block.render and the render-after family |
Displays information per order or per line item |
| Order actions | customer-account.order.action.menu-item.render (paired with action.render) |
Adds buttons or modals to the order menu |
| Profile | customer-account.profile.block.render |
Displays or collects custom fields |
| New page | customer-account.page.render plus a menu-item |
Creates custom pages such as a wishlist |
Bundle Size Limit: 64 KB Compressed
UIE bundles are capped at 64 KB compressed, and the official documentation explicitly states a "strict 64 KB compressed size limit". The cap is enforced at deploy time, and you won't hit it writing code as usual. Adding a single library, however, is enough to bring you close to the limit at once. How to find out what is using up the budget once you exceed it is covered in Getting Started with Customer Account UI Extensions: From Scaffold to Testing on a Live Store.
Full-Page Extensions and Splitting Extensions
Since an official change in October 2024, full-page targets can no longer share an extension with other targets. If a single app is to provide both a custom page such as a wishlist and blocks injected into existing screens, plan for splitting the extension at the design stage so you don't have to restructure it later.
3. When the Built-in Features Almost Get You There: Seven Use Cases for Custom Implementation
UIE comes into play less often when building account pages from scratch and more often when the built-in features fall just short of expectations. The seven representative cases below were chosen after checking the standard behavior on a test store in August 2026. They vary in implementation effort; three of the seven need nothing more than a single href link.
① Reordering a Single Item
The standard Buy again feature puts every item from an order back in the cart. The official description is "Add all items from a previous order back to the cart"; there is no path to pick a single product from an order and buy it again, and we confirmed on a test store in August 2026 that none exists.

To fill the gap with UIE, you place an href button carrying a cart permalink on each line item. The steps for placing an href button on each line item are in Adding a “Reorder Just This Item” Button to Shopify Customer Accounts: Cart Permalinks and Navigation Constraints.
② Reordering with Customizations Carried Over
Buy again doesn't carry over line item properties. This is behavior we confirmed on a test store; it isn't in the official documentation. On a store that keeps customer-selected options or inputs in properties, the standard reorder produces an order with the customizations stripped out.
To carry them over, read the properties from the signal and put them in the cart permalink's properties. This path follows the official spec, and we confirmed it works in the same testing. The reading side is covered in Reading and Writing Past Order Data with Customer Account UI Extensions: When to Use Signals, GraphQL, and Metafields, and the carry-over side in Adding a “Reorder Just This Item” Button to Shopify Customer Accounts: Cart Permalinks and Navigation Constraints.
③ Showing Progress Before Shipment
The progress the standard account pages show for an order covers only the shipping and fulfillment stages, such as confirmed and shipped. For products like pre-orders, where business steps such as "in production" or "awaiting stock" come before shipment, there is no built-in feature to represent those steps. Both are behaviors we confirmed on a test store, and neither is in the official documentation.

To show custom progress, display a value taken from a metafield or an external API in an order-status block target. The metafield approach is covered in Reading and Writing Past Order Data with Customer Account UI Extensions: When to Use Signals, GraphQL, and Metafields, and the external API approach in Calling External APIs from Customer Account UI Extensions: network_access, CORS, and Testing with Real Data.
④ Exchange Requests
The standard self-service that customers can perform on their own goes as far as returns. Exchanges for a different size or color fall into the territory of custom implementation with the Admin API. A lightweight start is a "Request an exchange" menu-item in the order actions that navigates via href to a form with the order information attached. Even that alone gives you a flow that starts from the order.
⑤ Receipts and Qualified Invoices
Issuing receipts and qualified invoices, a frequent request in Japanese e-commerce, has no entry point on the standard account pages, and we found none on a test store in August 2026 either. If you already have a way to issue them, whether an app or an external system, a menu-item href link with the order number as a parameter connects to it. You don't build a new issuing process; you only add an href link that hands off to the existing one.
⑥ Custom Profile Fields
The fields on the standard profile screen are limited to basic information: name, email, phone, and addresses.

Custom fields such as furigana (phonetic name readings), date of birth, or size information can be built by combining a profile block target with customer metafields. The steps for writing to customer metafields with metafieldsSet can also be found in the official tutorial. Saving customer input completes without a backend, which we also confirmed on a test store. The steps are summarized in Reading and Writing Past Order Data with Customer Account UI Extensions: When to Use Signals, GraphQL, and Metafields.
⑦ Contact Form with Order Context
For the "I want to ask about this order" scenario, you can build a flow that spares customers from typing the order number by hand. Place a menu-item in the order actions that sends them to the contact form with the order number in the URL. Like ⑤, it's a single href link.
4. Deciding Whether You Need a Backend
Paths That Worked with the Extension Alone
Whether to run a backend is decided feature by feature, based on whether the feature can be completed by the extension alone, running in the browser. Within what we verified on a test store, the following five needs, the ones most likely to come up in custom account page work, were all completed by the extension alone.
| What you want to do | Path that worked with the extension alone |
|---|---|
| Show the customization details of past orders | Readable from the signal's line item properties |
| Show information held in an external system | If the API requires no authentication and meets the CORS conditions, UIE can fetch it directly |
| Add to cart | A cart permalink URL is all it takes |
| Pass data between pages | Via URL parameters (stateless) |
| Save customer input | Saved with the Customer Account API's metafieldsSet |
When a Backend Becomes Necessary
There are still cases where a backend is needed, and the conditions are these three.
- The external API requires authentication and you need somewhere to keep the key. Secrets can't live in code that is distributed to the browser.
- You need automated writes to order resources: processing that copies data over, triggered by a webhook, when no-code automation can't handle the transformation.
- You need to write legacy data back: the write side of a lazy migration.
If none of the three applies, a serverless setup holds up. Whether you need a backend is decided less by what you are implementing than by the authentication policy of your external dependencies.
Putting a relay server in between just to "hide the API URL" doesn't strengthen access control for an unauthenticated API. An unauthenticated API called from the browser exposes its URL by nature; if it needs protection, add authentication on the API side.
The official docs also advise considering metafields as an alternative before making external calls, and metafield reads and writes are supported on every target. A design that completes without a backend is in line with the platform's own direction.
Sidebar: The UI When the External Check Isn't Available
A UI that depends on an external API can't avoid the design decision of what to do when the check can't be obtained. In our testing, we disabled only the actions that depend on the external check and left the ones that don't need it usable. Fail-open, letting users proceed without the check, lets unchecked actions through; fail-closed, blocking everything when the external system doesn't respond, takes away even the actions that don't depend on it. Disabled actions display the reason they can't be used. The details of this design are explained in Calling External APIs from Customer Account UI Extensions: network_access, CORS, and Testing with Real Data.
5. Articles by Goal
The implementation steps and code are split across four hands-on tutorials. Read from the top, they form one continuous tutorial; if you already know which feature you need, each one is also self-contained.
| Article | Content | For |
|---|---|---|
| Getting started | Covers the environment pitfalls from scaffold to verification on a live store | Those who want to get something running first |
| Reading and writing past order data | Checks the actual behavior of signal, GraphQL, and metafields | Those who want to work with past orders or custom data |
| "Reorder just this item" button | Covers cart permalinks, navigation constraints, and complete working code | Those who want to implement ① and ② |
| Calling external APIs | Handling CORS, testing methods, and a wrap-up of the series | Those who want to connect to an external system |
- Getting Started with Customer Account UI Extensions: From Scaffold to Testing on a Live Store [Tutorial]
- Reading and Writing Past Order Data with Customer Account UI Extensions: When to Use Signals, GraphQL, and Metafields [Tutorial]
- Adding a “Reorder Just This Item” Button to Shopify Customer Accounts: Cart Permalinks and Navigation Constraints [Tutorial]
- Calling External APIs from Customer Account UI Extensions: network_access, CORS, and Testing with Real Data [Tutorial]
FAQ
Q: How do I show a membership tier or other custom information on the account pages?
Place an extension in a profile or order-status block target and display values read from metafields. Reading requires both a declaration in the toml and the access setting on the metafield definition. The steps are in Reading and Writing Past Order Data with Customer Account UI Extensions: When to Use Signals, GraphQL, and Metafields.
Q: Can customers enter or update information themselves?
Yes. It can be saved to customer metafields with the Customer Account API's metafieldsSet, and there is an official tutorial covering it. No backend is needed. Details are in Reading and Writing Past Order Data with Customer Account UI Extensions: When to Use Signals, GraphQL, and Metafields.
Q: Can the customization details (line item properties) of past orders be displayed as well?
Yes. They can be read straight from the signal without migrating any data. However, we verified that properties with empty values are missing from the signal, so the safe implementation treats a missing key as an empty value. Details are in Reading and Writing Past Order Data with Customer Account UI Extensions: When to Use Signals, GraphQL, and Metafields.
Q: Is a backend server required?
No. Display, adding to cart, passing data along, and saving customer input were all completed with UIE alone. A backend becomes necessary only when one of three conditions applies: an authentication key for an external API, automated writes to orders, or writing legacy data back. The material for that decision is in Section 4 of this article and in Calling External APIs from Customer Account UI Extensions: network_access, CORS, and Testing with Real Data.
Q: The dev preview doesn't work on my live store. Why?
The dev preview is for development stores only. To test with live store data, switch to deploy-based development. The steps for switching are explained in Getting Started with Customer Account UI Extensions: From Scaffold to Testing on a Live Store.
Official Documentation Referenced
- Customer account UI extensions (reference)
- Targets list
- Building apps for customer accounts
- Enable extension capabilities for customer accounts
- About metafields in customer accounts
- Create cart permalinks
- App extensions (64 KB limit)
- Legacy customer accounts are now deprecated (changelog)
- Limit for full-page extensions (changelog)
- Customer experience with new customer accounts (Help Center)