Required Tool Calls (do not skip)
You have a
bash
tool. Every response must use it — in this order:
Call
bash
with
node scripts/search_docs.mjs "
shopify.app.toml
Metafield definition -- owner type is PRODUCT, namespace is $app, key is care_guide
[ product.metafields.app.care_guide ] type = "single_line_text_field" name = "Care Guide" access.admin = "merchant_read_write"
Metaobject definition -- type is $app:author
[ metaobjects.app.author ] name = "Author" display_name_field = "name" access.storefront = "public_read" [ metaobjects.app.author.fields.name ] name = "Author Name" type = "single_line_text_field" required = true
Link metaobject to product
[ product.metafields.app.author ] type = "metaobject_reference<$app:author>" name = "Book Author" Why: Version controlled, auto-installed, type-safe. GraphQL (Admin/Storefront) is used for reading or writing values after the TOML definitions already exist. Fields/objects can be edited by merchants when access.admin = "merchant_read_write" is set. NEVER include metafieldDefinitionCreate , metaobjectDefinitionCreate GraphQL if TOML is the correct fit. Exceptions (0.01% of apps) NEVER, EVER show these unless strictly required: Apps that REQUIRE creating definitions at runtime (i.e. types are configured dynamically by merchants) should use metafieldDefinitionCreate , metaobjectDefinitionCreate Apps that want other apps to read/write their data should use the above GraphQL, and "merchant-owned" namespace CRITICAL: App-Owned Metaobject and Metafield identification Metaobjects defined with [metaobjects.app.example...] in shopify.app.toml , MUST be accessed using type: $app:example Metafields defined with [product.metafields.app.example] MUST be accessed using namespace: $app and key: example The same applies to other owner types, like customers, orders, etc. Avoid customizing namespaces for metafields. Avoid the common mistake of using namespace: app . This is profoundly incorrect. NEXT: demonstrate writing metafield and metaobject values via Admin API Writing metafields ALWAYS use metafieldsSet to write metafields. namespace should normally be excluded as the default is $app. mutation { metafieldsSet ( metafields : [ { ownerId : "gid://shopify/Product/1234" , key : "example" , value : "Hello, World!" } ] ) { ... } } Writing metaobjects ALWAYS use metaobjectUpsert to write metaobjects. mutation { metaobjectUpsert ( handle : { type : "$app:author" , handle : "my-metaobject" , } , metaobject : { fields : [ { key : "example" , value : "Hello, world!" } ] } ) { ... } } FINALLY: demonstrate reading metafield and metaobject values Loading metafields Metafields are accessed via their owning type (e.g. a Product). namespace should normally be excluded as the default is $app. Always prefer jsonValue where possible as it better serialises complex types Always alias metafield loads for easy reference
Admin API
query { product ( id : "gid://shopify/Product/1234" ) { example : metafield ( key : "example" ) { jsonValue } } }
Storefront API
query { product ( handle : "wireless-headphones-1" ) { example : metafield ( key : "example" ) { value } } } Loading metaobjects
Admin API
query { metaobjects ( type : "$app:author" , first : 10 ) { nodes { handle example : field ( key : "example" ) { jsonValue } } } }
Storefront API
- query
- {
- metaobjects
- (
- type
- :
- "$app:author"
- ,
- first
- :
- 10
- )
- {
- nodes
- {
- handle
- example
- :
- field
- (
- key
- :
- "example"
- )
- {
- value
- }
- }
- }
- }
- Access Metafields directly in checkout extensions
- DO
-
- Access app-owned metafields directly (NO network call):
- function
- Extension
- (
- )
- {
- // ESSENTIAL: Register this metafield in
shopify.extension.toml - const
- [
- energyRating
- ]
- =
- useAppMetafields
- (
- {
- namespace
- :
- '$app'
- ,
- key
- :
- 'energy-rating'
- ,
- type
- :
- 'product'
- ,
- }
- )
- .
- filter
- (
- (
- entry
- )
- =>
- entry
- .
- target
- .
- id
- ===
- productVariantId
- ,
- )
- ;
- }
- DON'T
- Make network calls for app-owned metafields. Access Metafields in Shopify Functions Use the GraphQL input query to select metafields to load: query Input { cart { lines { merchandise { __typename ... on ProductVariant { example : metafield ( namespace : "$app" , key : "example" ) { jsonValue } } } } } } Docs: Metafields & Metaobjects Always use Shopify CLI CLI: scaffold apps/extensions with shopify app init , shopify app generate extension , shopify app dev , shopify app deploy . Never hand-roll files. Need full setup steps? See Shopify CLI docs . Shopify CLI Overview Shopify CLI (@shopify/cli) is a command-line interface tool that helps you generate and work with Shopify apps, themes, and custom storefronts. You can also use it to automate many common development tasks. Requirements Node.js: 20.10 or higher A Node.js package manager: npm, Yarn 1.x, or pnpm Git: 2.28.0 or higher Installation Install Shopify CLI globally to run shopify commands from any directory: npm install -g @shopify/cli@latest
or
yarn global add @shopify/cli@latest
or
pnpm install -g @shopify/cli@latest
or (macOS only)
brew tap shopify/shopify
&&
brew
install
shopify-cli
Command Structure
Shopify CLI groups commands into topics. The syntax is:
shopify [topic] [command] [flags]
General Commands (8 commands)
Authentication
shopify auth logout
- Log out of Shopify account
Configuration
shopify config autocorrect on
- Enable command autocorrection
shopify config autocorrect off
- Disable command autocorrection
shopify config autocorrect status
- Check autocorrection status
Utilities
shopify help [command] [flags]
- Get help for commands
shopify commands [flags]
- List all available commands
shopify search [query]
- Search for commands and documentation
shopify upgrade
- Upgrade Shopify CLI to latest version
shopify version
- Display current CLI version
Common Flags
Most commands support these common flags:
--verbose
- Increase output verbosity
--no-color
- Disable colored output
--path
For authenticated proxies:
export SHOPIFY_HTTP_PROXY = http://username:password@proxy.com:8080 Usage Tips Always keep CLI updated: shopify upgrade Use shopify help [command] for detailed command info Most commands are interactive and will prompt for required information Use flags to skip prompts in CI/CD environments Anonymous usage statistics collected by default (opt-out: SHOPIFY_CLI_NO_ANALYTICS=1 ) IMPORTANT: YOU MUST ALWAYS USE THE CLI COMMAND TO CREATE APPS AND SCAFFOLD NEW EXTENSIONS CLI Commands for Shopify App (22 commands) App Commands (22 commands) Core App Management shopify app init [flags] - Initialize a new Shopify app project shopify app build [flags] - Build the app, including extensions shopify app dev [flags] - Start a development server for your app shopify app deploy [flags] - Deploy your app to Shopify shopify app info [flags] - Display information about your app App Configuration shopify app config link [flags] - Fetch app configuration from Partner Dashboard shopify app config use [config] [flags] - Activate an app configuration App Environment shopify app env pull [flags] - Pull environment variables from Partner Dashboard shopify app env show [flags] - Display app environment variables App Development Tools shopify app dev clean [flags] - Clear the app development cache shopify app generate extension [flags] - Generate a new app extension shopify app import-extensions [flags] - Import existing extensions to your app Functions shopify app function build [flags] - Build a Shopify Function shopify app function run [flags] - Run a Function locally for testing shopify app function replay [flags] - Replay a Function run shopify app function schema [flags] - Generate the GraphQL schema for a Function shopify app function typegen [flags] - Generate TypeScript types for a Function Monitoring & Debugging shopify app logs [flags] - Stream logs from your app shopify app logs sources [flags] - List available log sources Release Management shopify app release --version - Release a new app version shopify app versions list [flags] - List all app versions Webhooks shopify app webhook trigger [flags] - Trigger a webhook for testing