Help: Can't access app installation metafields in Liquid block (Theme App Extension)

Hey everyone

I’m building a Shopify Theme App Extension, and I’m trying to access app installation metafields within a Liquid block but I’m stuck.

Here’s the setup:

  • I’m using app installation metafields since the data is install-specific.

  • Here’s my toml file (for the theme app extension):

    client_id = "123abc"
    name = "my-app"
    application_url = "https://my-frontend.io/"
    embedded = false
    handle = "my-app"
    
    [webhooks]
    api_version = "2025-07"
    
    [access_scopes]
    scopes = "customer_read_customers,read_content,read_customer_events,read_customers,read_discounts,read_fulfillments,read_inventory,read_locales,read_marketing_events,read_markets,read_metaobjects,read_orders,read_price_rules,read_product_listings,read_products,read_shipping,read_themes,unauthenticated_read_product_listings,write_content,write_customers,write_discounts,write_marketing_events,write_pixels,write_price_rules"
    optional_scopes = [ ]
    use_legacy_install_flow = false
    
    [auth]
    redirect_urls = [
      "https://my-backend.io/api/v1/auth/shopify/callback/",
      "https://my-backend.io/api/v1/auth/shopify/online-callback/"
    ]
    
    [app_proxy]
    url = "https://my-client.io"
    subpath = "my"
    prefix = "apps"
    
    
  • Here’s the Admin GraphQL mutation I use to create the metafields:

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

    With variables:

    {
       "metafields": [
            {
              "namespace": "settings",
              "key": "config",
              "type": "json",
              "value": "{\"foo\":\"bar\"}",
              "ownerId": "gid://shopify/AppInstallation/12345"
            }
          ]
        }
    

    And for the ownerId I use the AppInstallation id, using the below query:

    query {
      currentAppInstallation {
        id
      }
    }
    
  • Here’s the Admin GraphQL query I use to fetch the metafields:

    query GetAppInstallationMetafield($namespace: String!, $key: String!) {
      shop {
        myshopifyDomain
      }
      currentAppInstallation {
        id
        app {
            id
            title
        }
        metafield(namespace: $namespace, key: $key) {
          id
          namespace
          key
          value
          type
        }
      }
    }
    

    And this query shows the correct metafields data.

  • And here’s my Liquid code inside the block:

      <script>
      window.myConfig = "{{ app.metafields.settings.config }}"
      </script>
      
      {% if customer.accepts_marketing %}
       <meta name="customer-email" content="{{ customer.email }}" />
      {% endif %}
      
      {% schema %}
        {
          "name": "My App Embed",
          "target": "body",
          "javascript": "my-shopify.js",
          "settings": []		
        }
      {% endschema %}
    
    

The problem:

  • I can successfully create the metafield (no errors).
  • I can fetch it through Admin GraphQL (so it exists).
  • But inside the Liquid block, I get empty strings ('') - nothing renders.

I’ve double-checked namespaces and keys, but I might be missing something about how app installation metafields become accessible in a theme extension context.

Has anyone dealt with this before or knows if there’s an extra step needed (e.g., exposing them somehow to the storefront)?

Any help or insight would be super appreciated!