> For the complete documentation index, see [llms.txt](https://docs.ecwid.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ecwid.com/site-themes/develop-site-themes/sections/showcases.md).

# Showcases

Showcases are pre-configured variations of a section. When merchants add a section to a page through the Instant Site Editor, they see showcases as selectable presets — each with different default content, design values, and optionally a specific layout. Showcases let you demonstrate multiple visual styles for the same section.

### Folder Structure <a href="#folder-structure" id="folder-structure"></a>

Showcase files live in the `showcases/` directory alongside your section files:

```
sections/<section-name>/showcases/
├── 1.ts               # First showcase
├── 2.ts               # Second showcase
├── 3.ts               # Third showcase
└── translations.ts    # Showcase-specific translations
```

{% hint style="info" %}
**Naming Convention**

Both the filename and `showcaseId` are user-defined strings. The `showcaseId` is the identifier used throughout the product to reference a specific showcase.
{% endhint %}

### Showcase Properties <a href="#showcase-properties" id="showcase-properties"></a>

Each showcase is created using the `showcase.init()` factory:

```typescript
import { showcase } from '@lightspeed/crane-api';
```

<table><thead><tr><th width="148.41796875">Property</th><th width="199">Type</th><th width="106.70703125">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>showcaseId</code></td><td><code>string</code></td><td>Yes</td><td>Unique identifier for this showcase</td></tr><tr><td><code>blockName</code></td><td><code>string</code></td><td>Yes</td><td>Display name in the editor (translation key)</td></tr><tr><td><code>previewImage</code></td><td><code>object</code></td><td>Yes</td><td>Preview thumbnail shown in the editor</td></tr><tr><td><code>preset</code></td><td><code>string</code></td><td>No</td><td>Predefined visual preset (color scheme) for the showcase (<code>preset-a</code>…<code>preset-i</code>); defaults to <code>preset-a</code> when omitted — see Design Preset</td></tr><tr><td><code>content</code></td><td><code>Record&#x3C;string, ContentEditorDefaults></code></td><td>Yes</td><td>Content default overrides</td></tr><tr><td><code>design</code></td><td><code>Record&#x3C;string, DesignEditorDefaults></code></td><td>Yes</td><td>Design default overrides</td></tr><tr><td><code>layoutId</code></td><td><code>string</code></td><td>No</td><td>Selects a specific <a data-mention href="/site-themes/develop-site-themes/sections/settings/layouts.md">Layouts</a></td></tr></tbody></table>

#### Preview Image <a href="#preview-image" id="preview-image"></a>

The `previewImage` object has the same structure as the [IMAGE editor's `imageData`](/site-themes/develop-site-themes/sections/settings/content-editors.md#image) — a `set` with at least one image resolution key, and an optional `borderInfo`.

Each image entry supports the following properties:

| Property | Type     | Required | Description                                                                                                        |
| -------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
| `url`    | `string` | Yes      | Image file name referencing a file in the section's `assets/` directory                                            |
| `width`  | `number` | No       | Image width — together with `height`, defines the preview card aspect ratio (`paddingTop = height / width × 100%`) |
| `height` | `number` | No       | Image height — together with `width`, defines the preview card aspect ratio                                        |

Code example:

```typescript
previewImage: {
  set: {
    ORIGINAL: { url: 'custom_section_showcase_1_preview.jpg' },
    ORIGINAL: {
      url: 'custom_section_showcase_1_preview.jpg',
      width: 500,
      height: 300,
    },
  },
},
```

Image URLs reference files in the section's `assets/` directory.

#### Preview Card Aspect Ratio

The `width` and `height` values determine the aspect ratio of the preview card in the Instant Site Editor. The ratio is calculated as:

```typescript
paddingTop = (height / width) × 100%
```

For example, an image with `width: 500` and `height: 300` produces a `60%` ratio — a landscape preview card.

{% hint style="info" %}
Use actual image dimensions Set `width` and `height` to the real pixel dimensions of your preview image to ensure the card accurately represents the section's appearance.
{% endhint %}

### Content and Design Defaults <a href="#content-and-design-defaults" id="content-and-design-defaults"></a>

The `content` and `design` records provide default values for the section's fields. Keys must match those defined in your [`content.ts`](/site-themes/develop-site-themes/sections/settings/content-editors.md) and [`design.ts`](/site-themes/develop-site-themes/sections/settings/design-editors.md) files.

#### Design Preset

A showcase can declare an optional top-level `preset` field (next to `content` and `design`) that selects one of the section's predefined visual presets.

A **preset** is a named, product-defined visual style variant — primarily a color scheme — that the Instant Site Editor applies to the section. It lets a showcase ship in a look that stays consistent with the rest of the theme, on top of the showcase's own `content` and `design` defaults.

The value is a plain string and must be one of the following: `preset-a`, `preset-b`, `preset-c`, `preset-d`, `preset-e`, `preset-f`, `preset-g`, `preset-h`, or `preset-i`.

**What a preset actually does**

Preset do **not** introduce new colors, and do not let you author your own color values. A store has a single, theme-wide color scheme (a fixed list of brand colors).

A preset simply tells the Instant Site Editor **which mapping of that existing scheme** to apply to the section — effectively reordering which brand color fills each role (background, foreground, accent, etc.). For example, one preset may map `colorA → background` while another swaps it so `colorC → background`. The underlying theme and its colors are never edited; only the assignment of colors to the section changes.

{% hint style="warning" %}
**Presets are product-defined, not developer-defined**\
Third-party developers cannot define the color mappings themselves. The set of presets (`preset-a`…`preset-i`) and the color mapping each one represents are defined by the product (the store's active theme / Instant Site), not by your section. As a section author you can only select which preset a showcase ships with — you are picking from a predefined list, not creating new schemes.
{% endhint %}

Even though you don't own the mappings, choosing a preset is still useful:

* It ships your showcase in a look that stays consistent with the merchant's theme out of the box.
* You can preview and test your section under each preset while developing to see how it adapts to different color mappings and pick the one that looks best.
* The setting is not final — the merchant can change the preset later in the Instant Site Editor, and the section will re-map its colors accordingly. :::

{% hint style="info" %}
**When `preset` is omitted**\
The field is optional. When it is not set, the section falls back to its default preset (`preset-a`). Because it is optional, existing showcases that don't declare a `preset` keep working unchanged.
{% endhint %}

`preset` is authored — and kept — as a top-level field of the showcase. It is emitted as-is in the generated manifest, alongside (not inside) the `content` and `design` objects.

```typescript
showcase.init({
  showcaseId: '1',
  blockName: '$label.showcase_1.blockName',
  preset: 'preset-a',
  content: { /* ... */ },
  design: {
    title_style: design.default.text({
      size: 44,
      bold: true,
    }),
  },
});
```

The built manifest for the example above contains:

```json
{
  "preset": "preset-a",
  "design": {
    "title_style": { "size": 44, "bold": true }
  }
}
```

Use the `content.default.*()` and `design.default.*()` factories to create these defaults:

```typescript
import { content, design, showcase } from '@lightspeed/crane-api';

export default showcase.init({
  showcaseId: '1',
  blockName: '$label.showcase_1.blockName',
  previewImage: {
    set: { ORIGINAL: { url: 'showcase_1_preview.jpg', width: 500, height: 300 } },
  },
  content: {
    title: content.default.inputbox({
      text: '$label.showcase_1.title',
    }),
    description: content.default.textarea({
      text: '$label.showcase_1.description',
    }),
    cta_button: content.default.button({
      title: '$label.showcase_1.cta',
      buttonType: 'HYPER_LINK',
      link: 'https://example.com',
    }),
  },
  design: {
    title_style: design.default.text({
      font: 'global.fontFamily.heading',
      size: 44,
      bold: true,
      italic: false,
      color: '#333333',
    }),
    section_background: design.default.background({
      style: 'COLOR',
      color: 'global.color.background',
    }),
  },
});
```

### DECK in Showcases <a href="#deck-in-showcases" id="deck-in-showcases"></a>

For [DECK](/site-themes/develop-site-themes/sections/settings/content-editors.md#deck) editors, showcase defaults provide a `cards` array where each card has a `settings` record matching the deck's `defaultCardContent.settings` keys:

```typescript
content: {
  images: content.default.deck({
    cards: [
      {
        settings: {
          image_text: content.default.textarea({
            text: '$label.showcase_1.image_text_1',
          }),
          image_content: content.default.image({
            imageData: {
              set: {
                WEBP_LOW_RES: { url: 'slide_1_low.jpeg' },
                WEBP_HI_2X_RES: { url: 'slide_1_high.jpeg' },
              },
              borderInfo: {},
            },
          }),
        },
      },
      {
        settings: {
          image_text: content.default.textarea({
            text: '$label.showcase_1.image_text_2',
          }),
          image_content: content.default.image({
            imageData: {
              set: {
                WEBP_LOW_RES: { url: 'slide_2_low.jpeg' },
                WEBP_HI_2X_RES: { url: 'slide_2_high.jpeg' },
              },
              borderInfo: {},
            },
          }),
        },
      },
    ],
  }),
},
```

### Showcase Translations <a href="#showcase-translations" id="showcase-translations"></a>

Showcase-specific translations live in a separate `translations.ts` file inside the `showcases/` directory. This file follows the same format as [settings translations](/site-themes/develop-site-themes/sections/settings/translations.md) — a record keyed by language code:

```typescript
// showcases/translations.ts
import { translation } from '@lightspeed/crane-api';

export default translation.init({
  en: {
    '$label.showcase_1.blockName': 'Hero — Retail',
    '$label.showcase_1.title': 'Trending collections',
    '$label.showcase_1.description': 'Discover our favorite pieces this season.',
    '$label.showcase_1.cta': 'Shop Now',
    '$label.showcase_2.blockName': 'Hero — Minimal',
    '$label.showcase_2.title': 'New arrivals',
  },
  fr: {
    '$label.showcase_1.blockName': 'Héros — Vente au détail',
    '$label.showcase_1.title': 'Collections tendance',
    '$label.showcase_1.description': 'Découvrez nos pièces préférées de cette saison.',
    '$label.showcase_1.cta': 'Acheter maintenant',
    '$label.showcase_2.blockName': 'Héros — Minimal',
    '$label.showcase_2.title': 'Nouveautés',
  },
});
```

### Showcase Overrides <a href="#showcase-overrides" id="showcase-overrides"></a>

Showcases can also be overridden at the **template page level** using `showcase_overrides` on custom sections. This allows a template to reuse a section but adjust its showcase defaults without creating a new showcase file. See [Templates — Pages](/site-themes/develop-site-themes/templates/pages.md) for details.

### Validation <a href="#validation" id="validation"></a>

Crane validates showcases at build time. The following rules are enforced:

#### Content Validation

* Every key in `content` must exist in the section's `content.ts`. Unknown keys produce: *"Element is not defined in content.ts."*
* Editor types must match between showcase and `content.ts`. Mismatches produce: *"Element type mismatch: showcase has type X but content.ts has type Y."*
* Selectbox default values must match one of the options defined in `content.ts`. Invalid values produce: *"Option value is not defined in content.ts options."*
* DECK card settings keys must exist in `content.ts` `defaultCardContent.settings`. Invalid keys produce: *"Setting is not defined in content.ts defaultCardContent.settings."*

#### Design Validation

* Every key in `design` must exist in the section's `design.ts`. Unknown keys produce: *"Element is not defined in design.ts."*
* Editor types must match between showcase and `design.ts`. Mismatches produce: *"Element type mismatch: showcase has type X but design.ts has type Y."*

#### Layout Validation

* If `layoutId` is specified, it must match a layout defined in the section's `layout.ts`. Invalid IDs produce: *"LayoutId must exist in section's layout configuration file."*

#### Asset Validation

* Image URLs in showcase content must reference files that exist in the section's `assets/` directory. Missing images produce: *"Image is missing from assets folder."*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.ecwid.com/site-themes/develop-site-themes/sections/showcases.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
