Skip to content

Product Authoring

Use this guide when deciding what belongs in EmDash content and what belongs in Mika commerce records.

Host concept Mika concept Notes
Product entry ContentRefDTO Stable collection, id, optional locale. This is the join key; route slugs are host-owned.
Purchasable format SellableDTO One product can have multiple sellables for formats, bundles, licenses, subscriptions, or variants.
Purchase option PriceDTO Amount in minor units, currency, mode, fulfillment kind, interval fields, and provider refs.
Stock row AvailabilityDTO / stock repository Availability is read-time state; the host decides how inventory is stored and reserved.
Visible product page JSON-LD + copied purchase components The page must keep visible content, sellables, price, availability, and structured data in agreement.

A host product route may use a readable slug while Mika lookup uses a stable content ref:

const product = productBySlug(Astro.params.slug);
const sellablesResult = await Mika.catalog.sellables("products", product.id);

A matching API response can return sellables such as:

[
{
id: "sellable_panel_pack_mira",
content: { collection: "products", id: "mira-field-clipboard" },
title: "Mira Panel Pack",
active: true,
prices: [
{ id: "price_panel_pack_mira", amount: 1900, currency: "USD", mode: "one_time", active: true }
],
availability: { status: "in_stock", availableQuantity: 24, maxPerOrder: 3 }
}
]

The exact source DTO carries more fields; this example shows the authoring relationship, not every property.

The host product page owns:

  • slug resolution and 404 behavior;
  • editorial title, description, media, taxonomy, and layout;
  • locale handling;
  • the content ref passed to Mika.catalog.sellables(...);
  • ProductStructuredData props that match visible product state;
  • route-specific successPath, cancelPath, and returnTo values when defaults do not match copied checkout pages.

Mika owns the commerce contracts:

  • sellable and price DTO shapes;
  • action field names;
  • purchase model helpers;
  • availability snapshots;
  • JSON-LD template component behavior;
  • cart/wishlist/checkout operation semantics.

The seeded template uses seed/mika-actions.seed.json as fixture data and src/lib/mika-fixture-storefront.ts as resettable behavior. It proves product authoring shapes, but it is not Mika’s product editor or production schema.

Do not copy fixture IDs, readable download tokens, or in-memory behavior into production. Copy the mapping pattern: content entry to content ref to sellable to price to stock.

  • The host content entry resolves to a stable collection/id pair before calling Mika.catalog.sellables(...).
  • Visible product title, description, price, availability, and variants match the sellables passed to ProductStructuredData.
  • Unavailable or low-stock state is visible in the purchase UI before the buyer submits a form.

Next: Astro Storefront copies the action and component set. If you have not built a product route yet, use First Product Page first. Product JSON-LD shows the structured-data copy path.

  • ../emdash-mika/src/api/types.ts
  • ../emdash-mika/src/types/documents.ts
  • ../emdash-mika/src/model/builders.ts
  • ../emdash-mika/src/templates/astro/components/ProductStructuredData.astro
  • ../emdash-mika/src/templates/astro/components/ProductPurchase.astro
  • ../emdash-mika-template/seed/mika-actions.seed.json
  • ../emdash-mika-template/src/pages/products/[slug].astro
  • ../emdash-mika-template/src/lib/mika-fixture-storefront.ts