Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt

Use this file to discover all available pages before exploring further.

Storefront Snippets

Storefront snippets are Aqua/Liquid include files your app installs into a merchant’s theme namespace. Themes (or the merchant’s own storefront blocks) reference them with {% render 'your-snippet' %} just like a theme-author snippet. Use snippets when you ship reusable Liquid fragments your blocks or the merchant’s theme should be able to include — star ratings, badge components, formatted price markup, etc.

When to Use Snippets

  • A markup fragment your storefront block needs in two places.
  • A reusable component you want the merchant’s theme to be able to include directly (e.g. a “verified buyer” pill the merchant drops into their existing product card).
  • Liquid logic you want to share between two of your own blocks without duplicating it.
If you only need the fragment inside one block, just inline it — no snippet needed. If your app has no Liquid output at all, use App Scripts instead.

Manifest

Declare snippets in app.json under extensions.storefrontSnippets:
{
  "handle": "foundry-reviews",
  "name": "Foundry Reviews",
  "version": "1.0.0",
  "extensions": {
    "storefrontSnippets": [
      { "handle": "review-stars" },
      { "handle": "verified-buyer-pill" }
    ]
  }
}
FieldRequiredDescription
handleyesThe include name. Themes call {% render 'review-stars' %} (no path, no .aqua extension).
appIdnoApp identifier override; defaults to the install directory name.

Install — Inline Mode

When installing via POST /api/apps/install-extensions, ship the snippet body as a template string:
await fetch('https://store.launchmystore.io/api/apps/install-extensions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${accessToken}`
  },
  body: JSON.stringify({
    domainSlug: 'merchant-store',
    appHandle: 'foundry-reviews',
    extensions: {
      snippets: [
        { handle: 'review-stars',         template: '{% comment %}...{% endcomment %}<span class="stars">★★★★★</span>' },
        { handle: 'verified-buyer-pill',  template: '<span class="verified">Verified buyer</span>' }
      ]
    }
  })
});
The handler writes each snippet to:
public/extensions/{domainSlug}/{appHandle}/snippets/{handle}.aqua
and updates app.json so the manifest reflects the installed snippets.

Install — fromCatalog Mode

For first-party marketplace apps, the catalog directory public/marketplace-apps/apps/{appHandle}/snippets/ is copied as-is. Snippets live alongside the app’s blocks and assets under the same manifest.

Rendering — Naming Collisions

All installed apps share one Aqua include namespace. If two apps both install a snippet called review-stars, the render engine picks the one whose snippet directory was registered first; the loser’s snippet is shadowed silently. The install endpoint detects this case and logs a warning:
[install-extensions] Snippet handle "review-stars" already installed by foo-reviews on merchant-store; render order may shadow this app's snippet. Prefix the handle with the app handle to avoid collisions.
Best practice: prefix snippet handles with your app handle to keep them unique — foundry-review-stars rather than review-stars. This mirrors Shopify’s app-name-component-name convention.
{
  "extensions": {
    "storefrontSnippets": [
      { "handle": "foundry-review-stars" },
      { "handle": "foundry-verified-buyer-pill" }
    ]
  }
}

Using Snippets From Your Block

Reference your snippet by handle from your block’s .aqua template:
{% comment %} blocks/product-reviews.aqua {% endcomment %}
<div class="foundry-reviews">
  {% for review in product.metafields.foundry_reviews.recent.value %}
    <article>
      {% render 'foundry-review-stars', rating: review.rating %}
      <p>{{ review.body }}</p>
    </article>
  {% endfor %}
</div>
Snippets receive their parameters as regular Liquid variables. The custom LiquidJS fork in this engine auto-passes block_* variables into the snippet scope, so a snippet rendered from inside a block can access block.settings.<id> without re-passing it.

Using Snippets From The Merchant’s Theme

Once installed, the merchant (or their theme developer) can reference your snippet from their own theme files:
{% comment %} sections/product-card.liquid (merchant's theme) {% endcomment %}
<div class="product-card">
  ...
  {% render 'foundry-verified-buyer-pill', product: product %}
</div>
There is no permission gate — once your snippet is installed, it’s available to every Liquid file rendered for that merchant.

Inspecting Installed Snippets

ls public/extensions/<domainSlug>/<appHandle>/snippets/
# review-stars.aqua
# verified-buyer-pill.aqua

curl 'http://<domainSlug>.localhost:3000/api/apps/extensions?domainSlug=<domainSlug>' \
  | jq '.snippets'

Uninstalling

Snippets are removed by POST /api/apps/uninstall-extensions along with the rest of the app’s extension directory. Themes that still reference an uninstalled snippet render the failure inline — Liquid error: snippet 'foundry-review-stars' not found — so warn merchants before they uninstall an app whose snippets their theme uses.

See Also

  • Theme Blocks — Liquid blocks merchants place in sections (snippets are typically rendered from blocks).
  • App Scripts — auto-injected JavaScript.
  • Aqua Tags{% render %}, {% include %}, etc.