Channels

Set up the markets a shop sells in, each with its languages, currency, countries and the products it carries.

A channel is a market: the locales its pages speak, the currency its prices are in and the countries it serves. The home store sells in one channel, de, in German and English:

tests/fixtures/home/channels.json (trimmed)
{
    "channels": [
        {
            "id": "de",
            "label": { "de": "Deutschland", "en": "Germany" },
            "locales": ["de", "en"],
            "currency": "EUR",
            "countries": ["DE"]
        }
    ]
}

Labels, URLs and slugs exist per locale, prices per channel. countries guards privacy: the search log masks a phone number a shopper types into search, read as written there, before it keeps the query.

A release without channels.json derives it from the catalog: the locales its texts are keyed by or written in, the channels its offers name, and the currency their prices write. Changing channels.json rebuilds the indexes.

Reference: channels.json · locales · currency

The channel and locale a request gets

A request without channel is answered in the first channel, and without locale in that channel's first locale. The trace says which it got:

Terminal
curl -s 'http://127.0.0.1:7800/v1/search?query=sofa&debug=1' | jq -c '.trace.request | {channel, locale}'
200 · 4.9 ms · release b25a6aaa
{"channel":"de","locale":"de"}

A locale the channel does not serve is refused, and the answer names the ones it does:

Terminal
curl -s 'http://127.0.0.1:7800/v1/search?query=sofa&locale=fr' | jq -r '.violations[].message'
400 · 1.4 ms
The channel de serves de and en, not fr.

Channel, locale and context shows the same search in English.

Reference: channel · locale

Prices in the channel's currency

Every offer is in its channel's currency. An offer without currency takes the channel's, and a catalog line whose offer names another currency is left out and reported, since the shopper would see a wrong price.

Offer fields written on a variant, such as "price": 749.0, are its offer in the only channel. A shop with several channels gives each variant one offer per channel instead:

catalog.jsonl, one variant (trimmed)
{ "id": "SOFA-ASKA-2-GRAU", "offers": [{ "channel": "de", "price": 749.0, "availability": "in_stock" }] }

Reference: offers · currency

What a channel sells

An assortment is a selector for the products a channel sells. This one leaves out the lamps by Lumivo, such as the pendant lamp LEUCHTE-KUGEL:

channels.json
{
    "channels": [
        { "id": "de", "locales": ["de", "en"], "currency": "EUR", "assortment": { "not": { "brand": "Lumivo" } } }
    ]
}

The index run applies it to every variant. A variant it leaves out has no offer in the channel, so searches, facet counts, suggestions and the product page all leave it out, and no request can bring it back. The selector reads attributes, the brand and the offer fields of its own channel, never a relation.

POST $api/preview/find names the assortment when it is why a product is missing.

Reference: assortment

Context for rules

context declares the keys a request may carry, with the values each allows, so business customers can get rules of their own:

channels.json
{
    "channels": [{ "id": "de", "locales": ["de", "en"], "currency": "EUR" }],
    "context": { "customer_group": ["b2c", "b2b"] }
}

A request then sends "context": { "customer_group": "b2b" }, and a rule's when.context matches it (Rules). A rule that names an undeclared key fails validation, and a request that sends one is refused with a 400. Context never carries personal data. The home store declares none.

Reference: context · when.context

Next

On this page