Skip to main content

About metafields in customer accounts

Customer account UI extensions display standard Shopify data like order totals, addresses, and fulfillment status. But your app likely has its own data that isn't part of the standard Shopify model. For example, a loyalty app might store a customer's reward tier, or a product care app might attach washing instructions to each product.

Metafields are how you attach this custom data to Shopify resources like customers, orders, and products. Your extension can then read and display that data on customer account pages, or write new values based on customer input.


Your extension can read metafields in two ways. The method you use depends on which targets your extension runs in, because order status targets have access to pre-loaded metafield data that other targets don't.

Anchor to Customer Account APICustomer Account API

On any target, you can query metafields using the Customer Account API. This lets your extension pull in custom data that Shopify doesn't provide natively, such as a customer's loyalty tier, a preferred communication language, or membership details stored by your app. Without metafields, this data would only live in your own backend, and your extension would need network access to fetch it.

You can query metafields on Customer, Order, Company, and CompanyLocation resources. For example, a profile extension could query the customer's loyalty tier to display a membership badge:

GraphQL

shopify.customerAccount.query()
query {
customer {
metafield(namespace: "loyalty", key: "tier") {
value
}
}
}

On order status targets, your extension is tied to a specific order, so Shopify can pre-load metafields from resources associated with that order, including products, variants, the customer, and the shop. You declare which metafields you need in shopify.extension.toml, and Shopify delivers them automatically through appMetafields when the extension runs.

For example, an order status extension could display product care instructions without making any API calls. This is faster than querying at runtime because the data is delivered with the extension and requires no additional network call. Learn more in the Metafields API reference.

jsx

Order status extension
function Extension() {
const metafields = shopify.appMetafields.value;
const careEntry = metafields.find(
(entry) =>
entry.target.type === 'product' &&
entry.metafield.key === 'care_instructions',
);

if (!careEntry) return null;

return <s-text>{careEntry.metafield.value}</s-text>;
}

Your extension can also save customer input back to Shopify by writing to metafields. This lets you persist data like preferences, feedback, or profile details directly on Shopify resources, without needing your own backend database. The data is then available across Shopify (such as the admin, other extensions, or Shopify Flow) and persists across future extension sessions.

On any target, you can write metafields using the Customer Account API metafieldsSet mutation on Customer, Order, Company, and CompanyLocation resources.

For example, a profile extension could let a customer set a preferred nickname:

GraphQL

shopify.customerAccount.query()
mutation metafieldsSet($metafields: [MetafieldsSetInput!]!) {
metafieldsSet(metafields: $metafields) {
metafields {
key
value
}
userErrors {
field
message
}
}
}
Info

Metafield writes require customer_read_customers and customer_write_customers access scopes, and your app must have protected customer data access approved.

For a complete walkthrough, see the Building metafield writes into extensions tutorial.



Was this page helpful?