Help with useAppMetafields in Checkout UI Extension

Hi everyone,

I’m building a Checkout UI Extension using the purchase.checkout.block.render target, and I want to access my app-owned metafields.

Here’s a simplified version of what I’m doing:

export default reactExtension('purchase.checkout.block.render', () => <Extension />);

function Extension() {
  const metafields = useAppMetafields({
    key: 'cc_pdp',
    namespace: 'secret_keys',
    type: 'string', // ← not sure if this is correct
  });

  console.log("Metafields:", metafields);

  return (
    <>
      {metafields.map((entry, index) => (
        <Text key={index}>
          {entry.metafield.key}: {entry.metafield.value}
        </Text>
      ))}
    </>
  );
}

My metafields are created through the app and are attached to app namespace resources.

But I’m not seeing any data in the console. I suspect the issue is with the ` ?

Same metafiled i have tested on the liquid it was print the data correct.
`

App Meta data ::

{{ app.metafields.secret_keys.cc_pdp }}

`

:red_question_mark: My Questions:

  1. What should the correct type be when accessing metafields saved on app own meta ?
  2. Is purchase.checkout.block.render the right extension point to access App metafields value ?
  3. Do I need to filter by key manually, or will useAppMetafields give me all metafields for items will be automatically ?

Any help or sample code would be appreciated!

Thanks :folded_hands:

Hi @The_Sanjay

There’s a note in the documentation for the appMetafields field in this extension target that states:

Metafields on an app reserved namespace cannot be accessed by Checkout UI extensions.

Could you double check that your metafield isn’t registered privately?

@Dylan Thank you for your help!

Yes, I’ve created the app own-meta-filed — I believe this is a private app, correct?

here my code snippets.

 mutation CreateAppDataMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) {
      metafieldsSet(metafields: $metafieldsSetInput) {
        metafields {
          id
          namespace
          key
          value
        }
        userErrors {
          field
          message
        }
      }
    }

how Can i connect the app API to the checkout UI extension ?

Hi @The_Sanjay,

Based on the mutation example you shared, are you trying to read app data metafields? App data metafields are currently not supported in Checkout and customer Account UI extensions.

If you want to access custom data, you can use an app-owned metafield. This type of metafield is supported in Checkout and Customer Account UI extensions as of version 2025-04. You can set one up using the metafieldDefinitionCreate mutation in the Admin API. For a detailed example, please refer to this page.

To access custom data in extension code, you must use the $app prefix in the namesapce. Please see a detailed example here.

1 Like

Hi @avocadomayo ,

I am adding the code example of the Admin API code snippets below — please take a look at my implementation and let me know if there’s anything I should improve or if you have any suggestions.

GraphQL Admin API code snippets example

// Shopify Admin GraphQL mutation to set app-owned metafield

const mutation = `#graphql
  mutation CreateAppDataMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) {
    metafieldsSet(metafields: $metafieldsSetInput) {
      metafields {
        id
        namespace
        key
        value
      }
      userErrors {
        field
        message
      }
    }
  }
`;

const gql_app_own_id = await admin.graphql(`
  query {
    currentAppInstallation {
      id
    }
  }
`);

const { data } = await gql_app_own_id.json();
const res_app_own_id = data.currentAppInstallation.id;
console.log("App Installation ID:", res_app_own_id);

// Replace this with your actual recommendations data
const recommendations_appmeta = JSON.stringify(["product1", "product2", "product3"]);

const variables = {
  metafieldsSetInput: [
    {
      namespace: "app_result",
      key: "cc_pdp",
      type: "string",
      value: "recommendations_appmeta",
      ownerId: res_app_own_id,
    },
  ],
};

const response = await admin.graphql(mutation, { variables });
const responseData = await response.json();

console.log("Metafield Set Response:", responseData);

Checkout- UI extension.

import { useEffect } from "react";
import {
  reactExtension,
  useAppMetafields,
  BlockStack,
  Text,
} from "@shopify/ui-extensions-react/checkout";

// Entry point for the Checkout UI Extension
export default reactExtension("purchase.checkout.block.render", () => <Extension />);

function Extension() {
  // Fetch a specific app-owned metafield using $app prefix
  const [metafield] = useAppMetafields({
    namespace: "app_result",
    key: "cc_pdp",
    type: "string",
  });

  // Optional: Fetch all app-owned metafields
  const allAppMetafields = useAppMetafields();

  useEffect(() => {
    console.log("Metafield (cc_pdp):", metafield?.value);

    allAppMetafields.forEach((meta) => {
      console.log("App Metafield ->", meta.namespace, meta.key, meta.value, meta.type);
    });
  }, [metafield, allAppMetafields]);

// i am getting the result [] all time i have try with 

 appMetafield1 =  useAppMetafields({ "namespace": "app_result", "key": "cc_pdp", "type": "string" })
  console.log("  appMetafield1   -", appMetafield1)

  return (
    <BlockStack spacing="loose">
      <Text appearance="subdued">App Metafield Value:</Text>
      <Text>{metafield?.value ?? "No metafield found"}</Text>
    </BlockStack>
  );
}

validate the app meta filed into the liquid code
same app meta filed data - tested in the theme app extension it was render the data.

Result

I am getting the console log data

Hi @The_Sanjay,

In your example, you are using an app data metafields scoped to an app installation. This type of metafield is not supported in Checkout and Customer Account UI extensions. Please see this section for the list of supported metafield types.

Instead, you can use the metafieldDefinitionCreate mutation to create an app-owned metafield, which is supported in the UI extension you are trying to build. You can run this mutation in GraphiQL in the Shopify CLI.

mutation {
  metafieldDefinitionCreate(definition: {
    name: "My custom data",
    key: "my-key",
    namespace: "my-namespace",
    type: "single_line_text_field",
    ownerType: "PRODUCT"
  }) {
    createdDefinition {
      name
      namespace
      key
    }
  }
}

Once the metafield definition is created and you have set some values, you can read it like this in your extension JS code:

import {
  reactExtension,
  useAppMetafields,
  Text,
} from '@shopify/ui-extensions-react/checkout';

export default reactExtension(
  'purchase.checkout.cart-line-item.render-after',
  () => <Extension />,
);

function Extension() {
  const metafields = useAppMetafields();

  // if set up correctly, you should see metafields with namespace="$app:my-namespace" and key="my-key"
  return (
    <>
      {metafields.map((metafield) => (
        <Text>
          {metafield.metafield.namespace}.{metafield.metafield.key}="
          <Text appearance="subdued">{metafield.metafield.value}</Text>"
        </Text>
      ))}
    </>
  );
}
1 Like

@avocadomayo Thank you so much for your help! I’ve tried the suggested solution, but I’m a bit stuck on where exactly I can update the data for this.

Specifically, I’m working with the AppOwnedMetafield usage, and while the documentation mentions that we can access the data via the appMetafields API, it’s not clear how or where to actually update those values.

Here’s the doc I’m referring to:
:link: Metafields

If anyone could clarify how to update these app-owned metafields—either through the Admin API, UI Extensions, or somewhere else—I’d really appreciate it.

Thanks again!

Hi @The_Sanjay, custom data like metafields are owned by a certain resource type. To manage metafield values, you will need to update the owning resource.

For example, for a metafield of the PRODUCT owner type, you can use the productUpdate mutation in this example to set metafield values. Similarly, you can edit the product metafield directly via the product editor in Admin for the same result.

Here is another resource with additional instructions.

1 Like