How to access shop metafields in customer account UI extension?

Finally, I found the solution.

Step1: Create metafield definition.

GraphQL mutation:

mutation CreateMetafieldDefinition($definition: MetafieldDefinitionInput!) {
  metafieldDefinitionCreate(definition: $definition) {
    createdDefinition {
      id
      key
      name
      namespace
    }
    userErrors {
      field
      message
      code
    }
  }
}

Variables:

{
  "definition": {
    "name": "App Environment",
    "namespace": "$app:<my-app-name>",
    "key": "app_url",
    "description": "Metadata used to store the app environment",
    "access": {
      "admin": "MERCHANT_READ",
      "storefront": "PUBLIC_READ"
    },
    "type": "single_line_text_field",
    "ownerType": "SHOP"
  }
}

Step 2: Set metafields.

GraphQL mutation:

mutation MetafieldsSet($metafields: [MetafieldsSetInput!]!) {
  metafieldsSet(metafields: $metafields) {
    metafields {
      id
      key
      namespace
      value
      createdAt
      updatedAt
    }
    userErrors {
      field
      message
      code
    }
  }
}

Variables:

{
  "metafields": [
    {
      "key": "app_url",
      "namespace": "$app:<my-app-name>",
      "type": "single_line_text_field",
      "value": "<server-url>",
      "ownerId": "gid://shopify/Shop/<shop-id>"
    }
  ]
}

Step 3: Get shop metafields using storefront API on customer account UI extension.

const response = await fetch(
  `shopify://storefront/api/2025-01/graphql.json`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: `
        query {
          shop {
            metafields(identifiers: [
              { 
                namespace: "$app:<my-app-name>",
                key: "app_url"
              }
            ]) {
              namespace
              key
              value
            }
          }
        }
      `,
    }),
  }
);

const { data } = await response.json();
const value = data.shop.metafields?.[0]?.value;