Importing product data
Catalogue reads your range from a single data file in one of three formats: JSON, XML or CSV. Whichever you choose, the data is validated against the same schema at build time, so a file that imports cleanly in one format will import cleanly in another.
Point catalogue.config.json at your file and the format is detected from its
extension:
{
"data": "data/products.json"
}JSON
JSON is the most expressive format and the best choice if your products have
variants or custom attributes. The top level is an object with a products array.
{
"products": [
{
"id": "sku-1001",
"sku": "FN-A5-01",
"title": "Field Notebook A5",
"description": "Hardwearing A5 notebook, 120gsm, 96 pages.",
"category": "Stationery",
"price": 8.5,
"currency": "GBP",
"in_stock": true,
"stock": 240,
"image": "notebook-a5.jpg",
"images": ["notebook-a5.jpg", "notebook-a5-open.jpg"],
"tags": ["paper", "field"],
"attributes": {
"Material": "Recycled board",
"Weight": "180g"
},
"variants": [
{ "title": "Grey", "sku": "FN-A5-01-G", "price": 8.5, "in_stock": true },
{ "title": "Navy", "sku": "FN-A5-01-N", "price": 8.5, "in_stock": false }
]
}
]
}Reading the example, field by field:
iduniquely identifies the product and must be present on every item.priceis a plain number in major currency units (pounds, not pence).imagenames a file inassets/images/;imageslists additional views.attributesis a free-form map of label → value, shown as a specification list.variantsdescribes selectable options; each may overridepriceandin_stock.
XML
XML suits teams exporting from systems that already speak it. Use a root
<catalogue> element containing one <product> per item. Repeatable values —
images, tags, variants — use nested wrapper elements.
<?xml version="1.0" encoding="UTF-8"?>
<catalogue>
<product>
<id>sku-1001</id>
<sku>FN-A5-01</sku>
<title>Field Notebook A5</title>
<description>Hardwearing A5 notebook, 120gsm, 96 pages.</description>
<category>Stationery</category>
<price>8.50</price>
<currency>GBP</currency>
<in_stock>true</in_stock>
<stock>240</stock>
<images>
<image>notebook-a5.jpg</image>
<image>notebook-a5-open.jpg</image>
</images>
<tags>
<tag>paper</tag>
<tag>field</tag>
</tags>
<attributes>
<attribute name="Material">Recycled board</attribute>
<attribute name="Weight">180g</attribute>
</attributes>
<variants>
<variant>
<title>Grey</title>
<sku>FN-A5-01-G</sku>
<price>8.50</price>
<in_stock>true</in_stock>
</variant>
<variant>
<title>Navy</title>
<sku>FN-A5-01-N</sku>
<price>8.50</price>
<in_stock>false</in_stock>
</variant>
</attributes>
</product>
</catalogue>Notes specific to XML:
- Boolean fields accept
true/false(case-insensitive). - The first
<image>is treated as the primary image, exactly likeimagein JSON. attributesuse anameattribute for the label and element text for the value.
CSV
CSV is the quickest route from a spreadsheet. Each row is one product and the header row names the fields. Use a comma delimiter and UTF-8 encoding.
id,sku,title,category,price,currency,in_stock,stock,image,tags
sku-1001,FN-A5-01,Field Notebook A5,Stationery,8.50,GBP,true,240,notebook-a5.jpg,"paper;field"
sku-1002,PN-BLK-01,Rollerball Pen,Stationery,3.20,GBP,true,530,pen-black.jpg,"pens"
sku-1003,DSK-ORG-01,Desk Organiser,Office,14.00,GBP,false,0,organiser.jpg,"desk;storage"Because CSV is flat, a few conventions apply:
- Lists (
tags,images) go in a single cell, separated by semicolons:"paper;field". - Quoting — wrap any value containing a comma, semicolon or newline in double quotes.
- Attributes — add one column per attribute using the prefix
attr:. A column headedattr:Materialbecomes theMaterialattribute. - Variants are not supported in CSV. If your products have variants, use JSON or XML.
A CSV with attribute columns looks like this:
id,title,price,in_stock,attr:Material,attr:Weight
sku-1001,Field Notebook A5,8.50,true,Recycled board,180gValidation
Every import is validated when you run catalogue build. The build fails with a
clear message if a required field is missing, a type is wrong (for example, a
non-numeric price), or an id is duplicated. See
Troubleshooting for the common cases.
Schema reference
The same schema applies to all three formats.
Product
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the product. Must be unique across the file. |
sku | string | No | Stock-keeping unit shown to reps and included on orders. |
title | string | Yes | Product name, used as the heading. |
description | string | No | Longer description. Plain text; no markup. |
category | string | No | Category name, used for grouping and filtering. |
price | number | Yes | Price in major units (e.g. 8.5), not minor units. |
currency | string | No | ISO 4217 code (e.g. GBP). Defaults to the config currency. |
in_stock | boolean | No | Whether the product can be ordered. Defaults to true. |
stock | integer | No | Quantity on hand. Used by stock-display recipes. |
image | string | No | Primary image filename, relative to assets/images/. |
images | string[] | No | Additional image filenames. |
tags | string[] | No | Free-form labels for filtering and grouping. |
attributes | object | No | Map of label → value, rendered as a specification list. |
variants | Variant[] | No | Selectable options (JSON and XML only). |
Variant
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Variant name (e.g. a colour or size). |
sku | string | No | Variant-specific SKU. |
price | number | No | Overrides the product price when set. |
in_stock | boolean | No | Variant availability. Defaults to true. |
Types at a glance
- string — text. In CSV, quote values that contain a delimiter.
- number — decimal in major units. Use a full stop as the decimal separator.
- integer — whole number, no decimal point.
- boolean —
trueorfalse. - array — a list. Semicolon-separated in CSV; nested elements in XML.
Once your data imports cleanly, move on to the Liquid templating guide to shape how it looks.