App Manifest
Every LaunchMyStore app ships a singleapp.json file at the root of the
app package. The manifest declares the app’s identity (handle, name,
version) and every extension surface and function the app contributes.
At install time the platform writes the manifest into
extensions/{domainSlug}/{appHandle}/app.json per merchant.
At render time the storefront, checkout, admin, and customer-account
hosts read this file (through the local-manifest cache, 60s TTL) to
discover which extensions and functions to load. If app.json is
missing or unparseable, the app is silently skipped.
All keys under
extensions are camelCase. (Directories under
extensions/{domainSlug}/ whose name starts with _ are skipped at
manifest read time — but manifest fields are not filtered by prefix.)Top-level fields
string
required
Lowercase machine name for the app, e.g.
product-reviews-pro. Must
match the directory name under extensions/{domainSlug}/.
Uniqueness is enforced per merchant.string
required
Human-readable name shown in the merchant admin and the marketplace
listing.
string
Semver version string (e.g.
1.4.2). Used by the versioning system to
reconcile installed vs. published builds.string
Short marketing copy displayed on the marketplace card and admin
detail page.
string
Absolute URL to a square icon (PNG/SVG, recommended 256×256). Used by
the customizer block picker and admin sidebar.
string
Publisher name displayed on the marketplace listing.
string
Public website URL for the publisher.
string
Base URL the merchant is redirected to after install completes (the
app’s embedded admin entry point).
string[]
OAuth scopes the app requires (e.g.
read_products, write_orders).
See OAuth scopes.object
Container for every extension/function the app contributes. See the
per-key tables below.
Minimal example
Extensions
Theextensions object groups every extensible surface the app
contributes. Every key is optional; an app can use as few or as many as
it needs.
adminActions, printActions, and emailTemplates are accepted by
the install endpoint but are not stored inline in app.json
after install — they are persisted as per-handle schema files under
admin-actions/, print-actions/, and email-templates/
respectively, and surfaced through the admin-extensions API.storefrontBlocks
Liquid blocks merchants insert into theme sections via the customizer. Each entry produces ablocks/{handle}.aqua template and a
blocks/{handle}.schema.json block schema.
See Theme Blocks for the full block schema
spec, supported setting types, and target reference.
appBlocks
The delivery form of a storefront block, for apps served from your own domain. WherestorefrontBlocks describes the block for the marketplace,
appBlocks tells the platform where to fetch the actual files at install
time. Declare both.
Each entry’s template and schema are fetched over HTTP during install and
written into the merchant’s public/extensions/{shop}/{app}/blocks/
directory, so your app must serve them publicly (no auth) at stable URLs.
Snippets use the same pattern under
appEmbeds, with the source URL in
inlineHtml:
Block templates use plain
<style> and <script> tags, not the
{% stylesheet %} / {% javascript %} tags a theme uses. Those two tags
are a theme-bundling feature: the theme installer concatenates them into
the theme’s asset bundles, and nothing performs that step for app blocks —
so their contents render to the page as visible text and your CSS and JS
never run.Merchants place app blocks inside an
apps section. That section type is
provided by the platform, so it works on every theme whether or not the
theme author shipped a sections/apps.aqua of their own (a theme’s own
file always takes precedence).storefrontSnippets
Reusable Liquid partials any theme block or section can{% render %}.
Snippet handles share a single global namespace across all installed
apps — the install endpoint logs a warning when two apps register the
same handle and the filesystem-order winner is unpredictable. Prefix
your handles with the app handle to be safe.
storefrontEmbeds
Overlay/floating scripts (chat widgets, cookie banners, A/B tools) injected at<head>, body, or compliance_head based on the
target field. Merchants toggle each embed on/off in the customizer
“App embeds” tray.
See Storefront Embeds for full
schema and rendering behaviour.
appScripts
JavaScript files that the platform auto-injects on every storefront page render. Useful for installing pixels and chat widgets without editing the theme. TheloadStrategy controls how the <script> tag
is emitted: async (independent) or defer (preserves order, runs after
DOM). The loader itself defers injection to requestIdleCallback, so
scripts are already low-priority.
See App Scripts.
checkoutExtensions
Sandboxed iframes injected at named slots inside the checkout. The host communicates with the iframe through App Bridge overpostMessage.
postPurchaseExtensions
Iframe rendered on the order status (thank-you) page right after checkout (e.g. one-click upsells). Smaller wired-action set than checkout — focused on order summary + upsell purchase.adminExtensions
Iframes embedded inline on admin resource detail pages — product, order, customer, collection, discount, etc. The host (<AdminExtensionSlot target="…" />) fetches all extensions for a
target and renders each in a sandboxed iframe.
adminActions
Buttons on admin pages that open a modal iframe on click. Declared in the manifest but persisted to disk asadmin-actions/{handle}.schema.json
during install — the admin-extensions API merges them with
adminExtensions and tags them with type: 'admin_action'.
printActions
Buttons that open a printable view in a new window. Manifest carries either a Liquidtemplate (rendered server-side) or an appUrl
(iframe).
customerAccountExtensions
Iframe blocks rendered on the new customer-account pages (order status, dashboard, profile, order list). Same iframe contract as checkout extensions — bearer-token gated.webPixels
Sandboxed customer-event listener scripts loaded into an isolated iframe. Subscribe to events likepage_viewed, cart_updated,
checkout_completed. The manifest accepts either a remote scriptSrc
URL or an inlineScript string which the installer writes to
web-pixels/{handle}.js.
posExtensions
Iframe extensions for the Point-of-Sale app. Same shape asadminExtensions; targets start with pos.. The admin-extensions API
tags these with type: 'pos_extension' so the POS host can tell them
apart from regular admin blocks.
functions
Declarative WASM functions that fire in the cart → checkout → order-placement pipeline. Each entry maps to one of the nine supported function types. The install endpoint validatestype, handle, inputFields, and
network_access / allowed_hosts and rejects the install on any
violation.
orderRoutingRules
Declarative matchers that select a fulfillment location at order placement. Internally flattened into thefunctions dispatch list as
type fulfillment_location_rule.
emailTemplates
Per-event transactional email overrides. Each entry replaces the default template for one event (order_confirmation,
shipping_confirmation, etc.).
The authoritative copy of the email template is stored by the
platform — the install endpoint also deploys a read-only preview at
email-templates/{event}.json in your extension bundle.Validation rules
The install endpoint (POST /api/apps/install-extensions) enforces
the following at install time. Failures return HTTP 400.
Handle uniqueness
Handle uniqueness
Within a single
app.json, every handle inside one extension
array must be unique. Across apps, snippet handles (storefrontSnippets)
share a global namespace per merchant — collisions are logged but
do not fail the install.Function manifest validation
Function manifest validation
Every entry under
functions must have:type∈cart_transform,discount,shipping_rate,payment_customization,delivery_customization,order_validation,fulfillment_constraints,local_pickup_options,pickup_point_options- A non-empty
handlestring - Valid
inputFields(every leaf istrue/false, internal nodes are plain objects) if present - When
network_access: true, a non-emptyallowed_hostsarray of valid hostnames (no scheme, no path)
Function active limits
Function active limits
The backend
installApp() checks the merchant’s currently active
apps for each function type. If installing this app would push the
count over the per-type cap, install fails with HTTP 409. See
Function active limits for the per-type
caps.Target validation
Target validation
target strings on checkoutExtensions, adminExtensions,
posExtensions, customerAccountExtensions, and
adminActions/printActions are not validated against a closed
enum — but unknown targets simply won’t be picked up by any host.
Refer to the target lists on the relevant extension pages.Snippet handle conflicts
Snippet handle conflicts
Snippet handles share one Liquid resolver namespace across all apps
on a merchant. Installation continues on conflict but logs a
warning and render order is filesystem-dependent. Prefix snippet
handles with the app handle to avoid clashes.
Reserved directory names
Reserved directory names
Directories under
extensions/{domainSlug}/ whose name
starts with _ (underscore) are ignored at manifest read time and
can be used for scratch / debug data.Full example
See also
Extensions Overview
Every extension surface in one place.
Functions Overview
Declarative WASM functions for cart, shipping, discounts, validation.
App Types & Tiers
Public / private / first-party and the four pricing tiers.
App Lifecycle
Install, update, uninstall, and the version reconciliation pipeline.