> ## 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

> Reusable Liquid includes shared across blocks, sections, and themes

# 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](/extensions/theme-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](/extensions/app-scripts) instead.

## Manifest

Declare snippets in `app.json` under `extensions.storefrontSnippets`:

```json theme={null}
{
  "handle": "foundry-reviews",
  "name": "Foundry Reviews",
  "version": "1.0.0",
  "extensions": {
    "storefrontSnippets": [
      { "handle": "review-stars" },
      { "handle": "verified-buyer-pill" }
    ]
  }
}
```

| Field    | Required | Description                                                                                  |
| -------- | -------- | -------------------------------------------------------------------------------------------- |
| `handle` | yes      | The include name. Themes call `{% render 'review-stars' %}` (no path, no `.aqua` extension). |
| `appId`  | no       | App 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:

```javascript theme={null}
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:

```
extensions/{domainSlug}/{appHandle}/snippets/{handle}.aqua
```

and updates `app.json` so the manifest reflects the installed snippets.

## Install — fromCatalog Mode

For marketplace catalog apps, the `snippets/` folder shipped in the
app's catalog bundle 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
uses the `app-name-component-name` naming convention to avoid theme and
cross-app snippet collisions.

```json theme={null}
{
  "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:

```liquid theme={null}
{% 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 Aqua 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:

```liquid theme={null}
{% 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

```bash theme={null}
curl 'https://<your-store>.launchmystore.io/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](/extensions/theme-blocks) — Liquid blocks merchants
  place in sections (snippets are typically rendered *from* blocks).
* [App Scripts](/extensions/app-scripts) — auto-injected JavaScript.
* [Aqua Tags](/aqua/tags) — `{% render %}`, `{% include %}`, etc.
