Command Palette

Search for a command to run...

Guides › Customizer + AI Compatibility

Customizer + AI Compatibility

Expose sections, data sources, and actions so AI and the customizer can compose your app.

Customizer + AI Compatibility

If you want your app to work well with the Commercit customizer and AI, design it around surfaces and the shared host UI foundation.

The key rule is:

  • section = ready-made UI block
  • data_source = composable data
  • action = composable mutation

The strongest pattern is:

section + data_source + action

Every storefront section must also declare a Storefront Section Data Contract. For app sections this lives in storefront_contract inside commercit.json. For theme sections this lives in section.meta.ts as sectionContract. The contract declares renderMode, capabilities, and Storefront Data API blocks. Generated storefront HTML only receives those declared blocks.

For UI surfaces, import shared host primitives from:

  • @commercit/app-sdk/ui

For checkout, declare UI in the reviewed shipping module and use the isolated checkout-extension-protocol.v1 profile. Sandbox artifacts use @commercit/checkout-extension-sdk; see the Browser extension SDKs guide. Browser output is a proposal resolved by the platform host, never a direct commerce mutation.

What Merchants and AI Can Do

When an app is installed and registers section surfaces:

  • those sections appear in the customizer’s add-section flow
  • they can be placed in supported regions such as header, main, footer, or overlays
  • merchants can configure settings, move, hide, duplicate, and remove them
  • AI can recommend them, add them to the page, and change their settings

What merchants and AI cannot do:

  • edit the app’s section source code inside the customizer
  • access hidden app internals that are not declared as surfaces

App sections are read-only modules at the code level, but configurable at the template level.

Pick the Right Surface

Use section when you want ready-made app UI

Examples:

  • product page review widget
  • review carousel
  • UGC photo grid
  • floating social-proof widget
  • homepage loyalty banner

Use section when the developer wants the app to contribute a complete visual block that the merchant or AI can place directly on a page.

Use data_source when you want AI or host sections to consume your data

Examples:

  • reviews-list
  • review-summary
  • loyalty-balance
  • ugc-gallery-items

Use data_source when the value is the data itself, not a prebuilt section UI.

This lets AI build workspace-native sections powered by your app’s backend contract instead of only using your prebuilt sections.

Use action when you want AI or UI to trigger a mutation

Examples:

  • submit-review
  • mark-review-helpful
  • sync-reviews
  • redeem-points

Use action when something changes state or triggers work.

Best Pattern

If you only expose a section, AI can:

  • recommend it
  • add it to a page
  • configure its declared settings

If you expose section + data_source + action, AI can also:

  • build a workspace-native section that uses your app data
  • wire your app data into custom page layouts
  • trigger your app’s mutations through the declared action contract

That is the most future-proof option.

Shared UI Contract

App sections and admin panels should use the shared Commercit UI foundation instead of shipping a separate visual system.

Use:

import {
  Badge,
  Button,
  Card,
  CardContent,
  CardHeader,
  CardTitle,
  Container,
  SectionShell,
  Stack,
} from '@commercit/app-sdk/ui'

This keeps app surfaces aligned with:

  • native storefront sections
  • theme-authored custom sections
  • host-rendered admin panels

How AI uses your app outputs

AI can work with your app in two ways:

  1. add one of your ready-made section surfaces directly to the page
  2. create a custom workspace section that binds to your data_source and action surfaces

For the second path, the host stores bindings using unified surface moduleId values.

Binding rules:

  • AI discovers bindable surfaces through inspect({ what: "surfaces" })
  • bindings always reference moduleId
  • bindings never reference raw slugs
  • data is consumed with useBoundData(alias)
  • actions are invoked with useBoundAction(alias)

Example host binding payload:

{
  "_bindings": {
    "data": {
      "summary": {
        "moduleId": "app-surface-review-summary",
        "kind": "data_source",
        "params": {
          "product_id": "$product.id"
        }
      }
    },
    "actions": {
      "submit_review": {
        "moduleId": "app-surface-submit-review",
        "kind": "action"
      }
    }
  }
}

Example: Reviews App

For a reviews app, a strong surface mix looks like:

Sections

  • product-review-widget
  • review-carousel
  • ugc-gallery
  • floating-rating-widget
  • reviews-page

Data sources

  • reviews-list
  • review-summary
  • ugc-gallery-items

Actions

  • submit-review
  • report-review

With that shape:

  • the merchant can add prebuilt review sections directly
  • AI can recommend the correct review section for the page
  • AI can also build a custom workspace section that reads from reviews-list and review-summary

Example Manifest Slice

{
  "surfaces": {
    "sections": [
      {
        "slug": "review-carousel",
        "display_name": "Review Carousel",
        "description": "Shows customer reviews in a horizontal carousel",
        "category": "social-proof",
        "source": "sections/review-carousel.tsx",
        "settings_schema": [
          {
            "key": "heading",
            "type": "text",
            "label": "Heading",
            "default": "What customers are saying"
          }
        ],
        "default_settings": {
          "heading": "What customers are saying"
        },
        "surface": "inline",
        "preferred_region": "main",
        "ai_description": "Use this to show customer reviews on product and landing pages",
        "ai_tags": ["reviews", "ugc", "social-proof"]
      }
    ],
    "data_sources": [
      {
        "slug": "reviews-list",
        "display_name": "Reviews List",
        "description": "Returns review data for a product or the whole store",
        "handler": "handlers/reviews-list.ts",
        "output_schema": {
          "type": "object"
        },
        "ai_description": "Provides reviews for custom sections and AI composition",
        "ai_tags": ["reviews", "data"]
      }
    ],
    "actions": [
      {
        "slug": "submit-review",
        "display_name": "Submit Review",
        "description": "Creates a new product review",
        "handler": "handlers/submit-review.ts",
        "input_schema": {
          "type": "object"
        },
        "side_effects": ["writes review data"],
        "ai_description": "Submits a review from a storefront form",
        "ai_tags": ["reviews", "submit"]
      }
    ]
  }
}

Example SDK Usage

Ready-made section

import { defineSection } from '@commercit/app-sdk'
import { Card, CardContent, CardHeader, CardTitle } from '@commercit/app-sdk/ui'

export default defineSection({
  surface: 'inline',
  preferredRegion: 'main',
  component: function ReviewCarousel({ config }) {
    return (
      <Card>
        <CardHeader>
          <CardTitle>{String(config.heading ?? 'Reviews')}</CardTitle>
        </CardHeader>
        <CardContent>
          <p className="text-sm text-muted-foreground">
            A host-styled reviews section registered by the app.
          </p>
        </CardContent>
      </Card>
    )
  },
})

Composable data source

import { defineDataSource, docs } from '@commercit/app-sdk'

export default defineDataSource({
  handler: async (params) => {
    const productId = typeof params.product_id === 'string' ? params.product_id : null
    if (!productId) return { items: [] }

    const items = await docs.query('reviews', {
      filter: { product_id: productId },
      sort: { created_at: 'desc' },
      limit: 10,
    })

    return { items }
  },
})

Composable action

import { defineAction, docs } from '@commercit/app-sdk'

export default defineAction({
  handler: async (input) => {
    await docs.create('reviews', input)
    return { success: true }
  },
})

What AI Sees

The AI customizer does not need to know whether a surface is core or app-owned. It reads unified metadata such as:

  • display_name
  • description
  • category
  • settings_schema
  • surface
  • preferred_region
  • ai_description
  • ai_tags

That means your metadata matters. Do not leave it generic.

Good AI metadata example:

  • ai_description: “Use this to show product reviews below the main product details”
  • ai_tags: ["reviews", "pdp", "social-proof", "ugc"]

Weak AI metadata example:

  • ai_description: “Example section”
  • ai_tags: ["widget"]

Practical Checklist

If you want your app to be customizer- and AI-friendly, make sure it does all of these:

  • declares at least one meaningful section
  • uses a useful category
  • declares a complete settings_schema
  • provides sensible default_settings
  • writes strong ai_description
  • adds focused ai_tags
  • exposes data_source surfaces for the data you want AI to compose with
  • exposes action surfaces for mutations you want AI or UI to trigger

Important Limitation

Not every visual app problem is a section problem.

For example:

  • a full review widget is a strong section fit
  • a star badge inside every existing product card is more of a host extension point or future component-slot concern

If you need deep insertion into an existing host-owned UI component, that is not the same as adding a page section.