Documentation menu

Sources

The GatewaySources contract: how the gateway reads your source of truth, field by field — and the guarantees that govern what it renders.

The contract

A source is a lookup from a request URL to your source-of-truth data. Return the data when the URL is yours; return null (or undefined) when it isn’t. Sync or async both work — but resolvers run on the edge hot path (p95 < 50ms compute budget), so back them with your in-memory catalog, a KV cache, or a fast local store, not an origin round-trip.

GatewaySources
interface GatewaySources {            // all optional; missing source => pass through
  product?:  (url: URL) => ProductSource | null | Promise<ProductSource | null>
  policies?: (url: URL) => PolicySource[] | null | Promise<PolicySource[] | null>
  catalog?:  (url: URL) => CatalogItemSource[] | null | Promise<CatalogItemSource[] | null>
}

Resolution order & error containment

  • The order is fixed: productpoliciescatalog. The first source returning data wins — product wins when several would match a URL.
  • A source that throws is treated as "no match" and resolution continues with the next source. It never breaks your site.
  • If the render itself fails, the request passes through to HTML — the gateway never substitutes a lower-precedence document for the one that matched.
  • An empty policies/catalog array is no match. So is a missing source: configure only the resolvers you have.

ProductSource

One product detail page. Rendering order is fixed and front-loaded: title (linked to the canonical URL) → brand → price (compare-at struck through when present: ~~$120.00~~ $89.00) → availability → shipping → returns → variants table → description → attributes → images as markdown links. Absent optionals render nothing.

FieldTypeRequiredNotes
urlstringyesCanonical product URL — the linked title points here.
titlestringyesProduct title.
brandstringnoRendered as a Brand fact line.
descriptionstringnoRendered verbatim under a Description heading.
priceMoneyyesCurrent price. Minor units (see Money below).
compareAtPriceMoneynoStruck through next to the price when present.
availabilityAvailabilityyes'in_stock' | 'out_of_stock' | 'preorder' | 'backorder' — rendered with deterministic labels (In stock, …).
variantsProductVariantSource[]noRendered as a table: id / title / options / price / availability.
shippingShippingSourcenoFront-loaded shipping facts.
returnsReturnsSourcenoFront-loaded returns facts.
images{ url: string; alt?: string }[]noRendered as markdown links at the bottom.
attributesRecord<string, string>noMaterial, size-chart facts, etc. — rendered verbatim under Details.

ProductVariantSource, ShippingSource, ReturnsSource

FieldTypeRequiredNotes
ProductVariantSource.idstringyesVariant identifier (SKU-like id shown in the table).
ProductVariantSource.titlestringyesVariant title.
ProductVariantSource.priceMoneyyesPer-variant price.
ProductVariantSource.availabilityAvailabilityyesPer-variant stock state.
ProductVariantSource.skustringnoExplicit SKU when distinct from id.
ProductVariantSource.optionsRecord<string, string>noe.g. { Color: "Juniper Green" }.
ShippingSource.summarystringyesMerchant-authored shipping summary. Rendered verbatim.
ShippingSource.freeThresholdMoneynoFree-shipping threshold.
ShippingSource.regionsstring[]noShip-to regions.
ShippingSource.etaDays[number, number]no[min, max] delivery estimate in days, from the merchant.
ReturnsSource.summarystringyesMerchant-authored returns summary. Rendered verbatim.
ReturnsSource.windowDaysnumbernoReturn window in days.
ReturnsSource.urlstringnoLink to the full returns policy.

PolicySource

Policy documents (shipping, returns, warranty, …), rendered as linked headings + verbatim bodies.

FieldTypeRequiredNotes
titlestringyesPolicy title — rendered as a linked heading.
urlstringyesCanonical policy URL.
bodystringyesPolicy text. Rendered verbatim — never summarized or reworded.

CatalogItemSource

Collection/catalog listings, rendered as a markdown table (linked title, price, availability).

FieldTypeRequiredNotes
urlstringyesItem URL — the table’s linked title points here.
titlestringyesItem title.
priceMoneyyesItem price.
availabilityAvailabilityyesSame enum as products.

Money

FieldTypeNotes
amountnumberInteger minor units (cents for USD): 8900$89.00. Zero-decimal currencies are handled (¥4,900).
currencystringISO currency code, e.g. USD.

A non-integer amount throws rather than rounds — silently altering a price is never acceptable.

What rendering guarantees

Size budget: output is capped at maxBytes (default 5120 bytes, UTF-8). Buying facts are front-loaded, and truncation only ever removes content from the bottom (description, attributes, images) on whole lines, appending a fixed truncation note — never the front-loaded facts or the variants table. If the facts alone exceed the budget, they are emitted anyway: facts are never sacrificed to the byte budget.