Skip to content

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 ​

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

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

Showcase Properties ​

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

typescript
import { showcase } from '@lightspeed/crane-api';
PropertyTypeRequiredDescription
showcaseIdstringYesUnique identifier for this showcase
blockNamestringYesDisplay name in the editor (translation key)
previewImageobjectYesPreview thumbnail shown in the editor
presetstringNoPredefined visual preset (color scheme) for the showcase (preset-a…preset-i); defaults to preset-a when omitted — see Design Preset
contentRecord<string, ContentEditorDefaults>YesContent default overrides
designRecord<string, DesignEditorDefaults>YesDesign default overrides
layoutIdstringNoSelects a specific layout

Preview Image ​

The previewImage object has the same structure as the IMAGE editor's imageData — a set with at least one image resolution key, and an optional borderInfo.

Each image entry supports the following properties:

PropertyTypeRequiredDescription
urlstringYesImage file name referencing a file in the section's assets/ directory
widthnumberNoImage width — together with height, defines the preview card aspect ratio (paddingTop = height / width × 100%)
heightnumberNoImage height — together with width, defines the preview card aspect ratio
typescript
previewImage: {
  set: {
    ORIGINAL: {
      url: 'custom_section_showcase_1_preview.jpg',
      width: 500,
      height: 300,
    },
  },
},

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:

paddingTop = (height / width) × 100%

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

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

Content and Design Defaults ​

The content and design records provide default values for the section's fields. Keys must match those defined in your content.ts and design.ts 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 ​

A preset does not introduce new colors, and it does 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.

⚠️ 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.

💡 The value for section authors

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.

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

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.title',
      size: 44,
      bold: true,
      italic: false,
      color: '#333333',
    }),
    section_background: design.default.background({
      style: 'COLOR',
      color: 'global.color.background',
    }),
  },
});

DECK in Showcases ​

For 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 ​

Showcase-specific translations live in a separate translations.ts file inside the showcases/ directory. This file follows the same format as settings translations — 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 ​

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 for details.

Validation ​

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