Products
Products are the main searchable catalog of an e-shop — the items returned by the search widget and the recommendations API. Register the feed as a source of type Products.
<items><item> (zero or more)<?xml version="1.0" encoding="UTF-8"?><items><item><title>Aspirin 500 mg, 20 tablets</title><shop_item_id>SKU-12345</shop_item_id><url>https://shop.example.com/aspirin-500</url><availability>42</availability><price>89 Kč</price><price_old>109 Kč</price_old><availability_rank_text>In stock</availability_rank_text><category primary="true">Pain & fever | OTC medicines</category><category>Health supplements</category><brand>Bayer</brand><image_link_s>https://shop.example.com/img/asp-s.jpg</image_link_s><image_link_m>https://shop.example.com/img/asp-m.jpg</image_link_m><image_link_l>https://shop.example.com/img/asp-l.jpg</image_link_l><description><![CDATA[Fast pain relief, <strong>500 mg</strong> tablets.]]></description><parameters><param><name><![CDATA[Active substance]]></name><value><![CDATA[Acetylsalicylic acid]]></value></param><param><name><![CDATA[Pack size]]></name><value><![CDATA[20 tablets]]></value></param></parameters><labels>sale,new</labels><product_code>ASP-500-20</product_code></item></items>
<!ELEMENT items (item*)><!ELEMENT item (title, shop_item_id, url, availability, price, price_old?, availability_rank_text?, category*, brand?, image_link_s?, image_link_m?, image_link_l?, description?, parameters*, labels?, product_code?)><!ATTLIST item language CDATA #IMPLIED><!ELEMENT title (#PCDATA)><!ELEMENT shop_item_id (#PCDATA)><!ELEMENT url (#PCDATA)><!ELEMENT availability (#PCDATA)><!ELEMENT price (#PCDATA)><!ELEMENT price_old (#PCDATA)><!ELEMENT availability_rank_text (#PCDATA)><!ELEMENT category (#PCDATA)><!ATTLIST category primary (true|false) "false"><!ELEMENT brand (#PCDATA)><!ELEMENT image_link_s (#PCDATA)><!ELEMENT image_link_m (#PCDATA)><!ELEMENT image_link_l (#PCDATA)><!ELEMENT description (#PCDATA)><!ELEMENT parameters (param*)><!ELEMENT param (name, value*)><!ELEMENT name (#PCDATA)><!ELEMENT value (#PCDATA)><!ELEMENT product_code (#PCDATA)><!ELEMENT labels (#PCDATA)>
Children must appear in the order shown above.
| Element | Required | Type | Searched | Meaning |
|---|---|---|---|---|
title | yes | text | yes | Product name. Full-text and prefix (as-you-type) searchable. An item with an empty title is skipped. |
shop_item_id | yes | text | no | Your unique product identifier. Returned as externalId and used as shopItemId by the recommendations API. An item with an empty id is skipped. |
url | yes | text | no | Link to the product page. |
availability | yes | integer | no | Stock indicator as a whole number (e.g. units in stock; 0 = unavailable). In-stock items rank higher. A non-numeric value is treated as 0. |
price | yes | text | filter | Pre-formatted price string, shown verbatim (e.g. "89 Kč"), and also read as a number for the price filter. See Prices below. |
price_old | no | text | no | Original price before a discount. Stored and returned verbatim alongside price, and shown struck through next to it in the widget. Never read as a number. |
availability_rank_text | no | text | no | Human-readable availability label (e.g. "In stock", "Skladem"). Returned with the result. |
category | no | text | — | Category name; repeatable; optional primary attribute. See Categories and the primary flag. Matched against a Categories feed's hierarchy to resolve a URL. |
brand | no | text | — | Single brand name. Matched against a Brands feed to resolve a URL. An empty <brand> is ignored. |
image_link_s | no | text | no | Small image URL. |
image_link_m | no | text | no | Medium image URL. |
image_link_l | no | text | no | Large image URL. |
description | no | text | yes | Product description; HTML allowed (wrap in CDATA). Indexed as the result's annotation. |
parameters | no | element | yes | Attribute name/value pairs; repeatable. Searchable but not returned. See Parameters below. |
labels | no | text | filter | Comma-separated merchant tags (e.g. akce,novinka,bio). Shown on the result and offered as a checkbox filter. Used verbatim. See Labels below. |
product_code | no | text | no | Manufacturer/product code, SKU, or EAN. Used for exact-match lookups and shown in click analytics. Optional in the schema, but strongly recommended — omit it and those lookups cannot match. |
<price> is what the shopper sees: whatever you send is stored and displayed
verbatim, currency and all. On top of that we read a number out of it, which
is what the price filter — the range slider with the histogram above it — runs
on.
<price>9 999 Kč</price>
Rules:
9 999 Kč, 9999 Kč and 9999Kč are the same 9999.. or , followed by exactly one or two digits is the
decimal point; everything else is a group separator. So 1 299, 1.299 and
1,299 are all 1299, while 19,99 and 19.99 are both 19.99. Two decimal
places are the limit.Kč,
CZK, € — is kept as the label the filter shows. Send one currency per
feed: a feed that mixes them gets a filter with no currency label, because
labelling euro amounts "Kč" would be worse than saying nothing.0 means "price not stated". A product priced at 0 is still imported
and still displayed as you sent it, but it is left out of the filter
entirely — out of the range, out of the histogram, and never returned by a
price range. Otherwise a handful of zero-priced items would drag the low end
of every slider down to nothing.cena na dotaz, od 39 Kč,
39 Kč / ks — the product imports, ranks and displays exactly as before, it
simply does not take part in the price filter. There is no error and no
rejected item.price_old is display only. It is never parsed, and nothing is derived
from it — a discount is a label you send, not something we infer.The filter appears only where an admin has placed the Price filter block in the Visual settings, and only for product results: articles, categories and brands carry no price.
Products often carry attributes that never appear in the title or the
description — grape variety, volume, active substance, pack size. Send them as
<parameters> and customers can find the product by that content: a search for
nebbiolo will return a wine whose only mention of it is
Grape variety: Nebbiolo.
<parameters><param><name><![CDATA[Grape variety]]></name><value><![CDATA[Nebbiolo]]></value></param><param><name><![CDATA[Volume]]></name><value><![CDATA[0,75 l]]></value></param></parameters>
Rules:
<parameters> behaves exactly as it
does today. Nothing about your existing results changes.<parameters> goes after <description> and before
<labels>. The content model is ordered, so a wrapper placed anywhere else
fails validation — and validation is all-or-nothing, so one misplaced wrapper
rejects the whole feed, not just that item.<parameters> holding many <param>,
or one <parameters> per <param> repeated — both are accepted and produce
the same result.Award three times gives you three
pairs; nothing is merged or deduplicated.<param> needs a non-empty <name> and <value>. One that doesn't is
skipped on its own — the product still imports and the rest of its parameters
are kept.0,75 l,
13 %, 20 tablets. Values are free text and are indexed as written.What parameters do not do yet:
Because names are indexed exactly as you send them, consistency pays off:
Grape variety and Grape varieties are two unrelated strings to the search
engine, not one attribute.
A product may carry merchant-defined tags — akce, novinka, bio. Send them
as one comma-separated <labels> element and they appear as badges on the
result and as a checkbox filter in the search panel.
<labels>akce,novinka,bio</labels>
Rules:
<labels> behaves exactly as it does
today.<labels> goes after <parameters> and before
<product_code>. As with <parameters>, the content model is ordered and one
misplaced element rejects the whole feed.language attribute). Nothing is translated, renamed or
reordered by us.price_old. Whether an item is on sale is
your call, and a label you send is one you can also rename or switch off
without waiting on a release.akce, ,bio,akce becomes akce and bio.Akce and akce are two different labels, because
only you know which spelling the shopper should see.Keep the vocabulary small and stable. Every distinct value becomes a checkbox in the panel, and the filter shows the 50 most common — a label unique to one product helps nobody find anything.
Selecting several labels widens rather than narrows: a product shown matches at least one of the checked labels.
The <item> element accepts an optional language attribute, so one feed can
carry every language version of your content — including per-market prices, URLs
and availability. Omit it and the record uses the instance's default content
language.
See Multi-language feeds.