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

# App Listing & Detail Page

> How marketplace listings and the in-admin detail page render from your Apps row, and how to author every field that controls them.

# App Listing & Detail Page

LaunchMyStore renders an installed app's *in-admin detail page*
(`/admin/apps/{handle}`) and the *marketplace listing*
(`/marketplace/{handle}`) from the same `Apps` row. This page is the
field-by-field reference for everything you control on those two screens
— what shows where, how to author it, and the publishing flow.

This guide is for developers using the **Developer dashboard** at
[app.launchmystore.io/developer/apps](https://app.launchmystore.io/developer/apps)
to ship public apps to the marketplace.

## Where each field shows up

| Field                                                  | Marketplace listing |     In-admin detail page    |
| ------------------------------------------------------ | :-----------------: | :-------------------------: |
| `name`                                                 |  card title + hero  |         header title        |
| `iconUrl`                                              |   card + hero icon  |         header icon         |
| `tagline`                                              |    card subtitle    |       header subtitle       |
| `description`                                          |    short summary    |              –              |
| `categories`                                           |   category filter   |              –              |
| `pricing`                                              |     price label     |          "Plan" row         |
| `images` (screenshots)                                 |       gallery       |              –              |
| `worksWith`                                            |  "Works with" pills |      "Works with" pills     |
| `installationGuide`                                    |          –          | **Getting started** section |
| `tutorialVideoUrl`                                     |        embed        |            embed            |
| `privacyPolicyUrl`, `supportEmail`, `documentationUrl` |     footer links    |         footer links        |
| `extensions.settings`                                  |          –          |        Settings card        |
| `extensions.{storefrontBlocks, checkoutExtensions, …}` |          –          |     "What this app adds"    |

## Authoring fields at app creation

Open `/developer/apps/create`. The **Listing Details** section captures
the three fields that change how the in-admin detail page reads:

<ParamField path="tagline" type="string ≤100">
  The one-line subtitle under your app name. Both screens show this.
</ParamField>

<ParamField path="worksWith" type="string[]">
  Newline-separated list of third-party services / platforms (e.g.
  `Klaviyo`, `Google Shopping`, `Meta Shops`). Renders as pills.
</ParamField>

<ParamField path="installationGuide" type="markdown">
  Setup instructions shown as the *Getting started* section on the
  in-admin detail page. See [Writing a good installationGuide](#writing-a-good-installationguide).
</ParamField>

You can edit all of these later from `/developer/apps/{appId}` →
**Listing** tab. Saving there issues a `PATCH` that the platform
live-replays into both the marketplace listing and every merchant's
in-admin detail page — **no re-publish needed**.

## Detail page anatomy

```
+--------------------------------------------------------------+
| [icon]  Your App Name                  [Install on store] ▶  |
|         tagline goes here                                    |
+--------------------------------------------------------------+
|  Note: Not installed on your store yet.                      |  ← only when no installation
+--------------------------------------------------------------+
|  ⚙ Settings                                                  |
|  └─ rendered from extensions.settings                        |
+--------------------------------------------------------------+
|  🚀 Getting started                                           |
|  └─ rendered from `installationGuide` (Markdown)             |
|  └─ if blank, auto-generated from your extension manifest    |
+--------------------------------------------------------------+
|  Puzzle  What this app adds                                  |
|  └─ list of extensions: blocks, snippets, functions, etc.    |
+--------------------------------------------------------------+
|  Works with                                                  |
|  └─ pills from `worksWith`                                   |
+--------------------------------------------------------------+
|  Support · Privacy · Docs                                    |
+--------------------------------------------------------------+
```

The **Install** button only appears when the merchant has no
installation row for this app. Clicking it opens
`/marketplace/{handle}` where the standard OAuth → install flow runs.

## Writing a good `installationGuide`

This is plain Markdown. The renderer is intentionally minimal — it
supports:

* Headings: `#`, `##`, `###`
* Bold (`**text**`), italic (`*text*` or `_text_`), inline code (`` `text` ``)
* Links: `[label](https://…)` — open in a new tab automatically
* Ordered lists (`1.`, `2.`, …) and unordered lists (`-`, `*`, `+`)
* Paragraphs (separated by a blank line)

It does **not** support: HTML, images, tables, footnotes, or fenced
code blocks. Keep instructions short and step-driven; merchants are
usually on their first install when they read this.

### Example — extension-only app

```markdown theme={null}
# Get Plinth running in 60 seconds

1. Open **Appearance → Themes** and click *Customize* on your live theme.
2. In the section picker, add the *Plinth bar* block above the **Header**.
3. Pick a style — *Trust badges*, *Free shipping*, or *Announcement*.
4. Set your **free-shipping threshold** under the **Settings** card on this page.

That is it — refresh your storefront and the bar appears across every page.

**Tip:** schedule a holiday-only bar by toggling *Show on homepage* off.
```

### What happens if you leave it blank

The detail page auto-generates a "Getting started" section from your
extension manifest:

| Extension type                      | Auto-generated copy                                                 |
| ----------------------------------- | ------------------------------------------------------------------- |
| Storefront blocks                   | "Open *Appearance → Themes* and add the `{block}` block."           |
| Snippets                            | "Use `{% raw %}{% render '{handle}' %}{% endraw %}` in your theme." |
| Checkout / post-purchase extensions | "Renders automatically at checkout."                                |
| Admin blocks                        | "Appears at *{target}* in admin."                                   |
| Functions                           | "Runs as a `{type}` function."                                      |
| Settings                            | "Configure under *Settings* on this page."                          |

This is good enough to ship a v1, but writing your own guide is
strongly recommended — auto-generated copy is generic and will not
tell merchants the *why* (e.g. "set a threshold of \$75 to recover 80%
of abandoned carts").

## Field reference

These are the columns on the `Apps` table that the developer
dashboard exposes. All are optional unless marked **required**.

|                                                  Field | Type        | Notes                                                                                                                                                                                                                                             |
| -----------------------------------------------------: | :---------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|                                               `handle` | string      | **required**, lowercase + hyphens, immutable after publish                                                                                                                                                                                        |
|                                                 `name` | string      | **required**                                                                                                                                                                                                                                      |
|                                          `description` | text        | shown on the marketplace card                                                                                                                                                                                                                     |
|                                              `tagline` | string ≤100 | shown under the app name                                                                                                                                                                                                                          |
|                            `developer`, `developerUrl` | string      | populated by backend from auth                                                                                                                                                                                                                    |
|                                               `appUrl` | URL         | if set, the in-admin page renders an **iframe** instead of the extension-only detail page                                                                                                                                                         |
|                                     `tutorialVideoUrl` | URL         | optional embed                                                                                                                                                                                                                                    |
|                                                 `type` | enum        | `public`, `private`, `first-party`                                                                                                                                                                                                                |
|                                              `version` | semver      | e.g. `1.0.0`                                                                                                                                                                                                                                      |
|                                           `categories` | string\[]   | one of: `selling-products`, `store-design`, `store-management`, `finding-products`, `orders-and-shipping`, `marketing-and-conversion`                                                                                                             |
|                                            `worksWith` | string\[]   | third-party services (Klaviyo, Meta Shops, etc.)                                                                                                                                                                                                  |
|                                    `installationGuide` | text        | Markdown setup instructions                                                                                                                                                                                                                       |
|                                              `pricing` | object      | `{model, monthlyPrice, yearlyPrice, currency, trialDays, usage?}` — `usage: {unitName, unitAmount, cappedAmount, terms?}` declares a metered component (see [Usage Billing](/billing/usage-billing))                                              |
|                                       `commissionRate` | number      | platform default `0.06` (6%)                                                                                                                                                                                                                      |
|                                               `images` | object\[]   | screenshots — `{url, alt}`                                                                                                                                                                                                                        |
|                                              `iconUrl` | string      | Hosted URL to a **square** icon. Supply a 256×256 PNG or SVG (renders down to \~52×52 in the marketplace card / admin header). Transparency supported; URL ≤ 2048 chars, no `data:` URIs. No upload endpoint — host it yourself and pass the URL. |
|                                         `redirectUrls` | string\[]   | OAuth callbacks                                                                                                                                                                                                                                   |
|                                               `scopes` | string\[]   | requested OAuth scopes; validated against `ALL_SCOPES`                                                                                                                                                                                            |
|                                           `extensions` | object      | manifest of `storefrontBlocks`, `storefrontSnippets`, `checkoutExtensions`, `postPurchaseExtensions`, `adminExtensions`, `functions`, `settings`                                                                                                  |
|                                            `isPremium` | boolean     | true for paid-only apps                                                                                                                                                                                                                           |
| `privacyPolicyUrl`, `supportEmail`, `documentationUrl` | URL/email   | shown on the detail page                                                                                                                                                                                                                          |

`extensions.settings` is what powers the in-admin **Settings** card.
Each entry is `{type, key, label, default, ...}` (text, number,
boolean, select). Settings render in disabled / preview mode if the
merchant has not installed the app yet.

## Two render modes for the in-admin page

`/admin/apps/{handle}` chooses one of two layouts based on whether
`appUrl` is set:

<CardGroup cols={2}>
  <Card title="AppEmbedFrame" icon="window">
    Used when `appUrl` is set. Renders **your hosted iframe** with the
    App Bridge SDK loaded. You own the entire UI inside the frame.

    Use this for apps with a hosted dashboard, custom forms, or any UI
    beyond declarative extensions.
  </Card>

  <Card title="ExtensionOnlyDetailPage" icon="puzzle-piece">
    Used when `appUrl` is `null` / empty. Platform-rendered header +
    Settings + Getting started + extensions list.

    This is the right choice for **declarative apps** (theme blocks,
    WASM functions, admin blocks) that don't need a hosted dashboard.
  </Card>
</CardGroup>

If you want the platform-rendered detail page, **leave `appUrl`
empty**.

## Publishing flow

<Steps>
  <Step title="Create the app">
    At `/developer/apps/create` choose **Save as Draft** or **Submit
    for Review**. Drafts let you edit freely without affecting any
    merchant.
  </Step>

  <Step title="Add extensions and functions">
    At `/developer/apps/{appId}` use the tabs *Extensions*, *Functions*,
    *Webhooks* to register what your app contributes to the storefront,
    checkout, and admin.
  </Step>

  <Step title="Submit for review">
    Status moves `draft → review → published`. Review checks scopes,
    redirect URLs, and listing copy.
  </Step>

  <Step title="Merchants install">
    Once published, merchants see your app on `/marketplace`. Install
    creates the installation record and deploys your blocks /
    snippets to the merchant's
    `extensions/{domainSlug}/{handle}/` bundle on
    LaunchMyStore.
  </Step>
</Steps>

A clean uninstall removes the deployed bundle and refreshes the caches
automatically — no leftover files pollute the merchant's storefront.

## See also

* [App Lifecycle](/getting-started/app-lifecycle) — install → uninstall flow + webhooks
* [App Versioning](/getting-started/app-versioning) — semver, rollback, sandbox testing
* [Extensions Overview](/extensions/overview) — what each extension type does
* [Authentication](/getting-started/authentication) — OAuth scopes + session tokens
* [App Bridge Overview](/app-bridge/overview) — talking to the host from your iframe
