Product import
Reached from: Import on the catalogue, or ?action=import
Permission: Import Products
1. What the importer is
A three-step CSV loader for creating many products at once.
products.import is a separate permission from products.createA role that can create products one at a time does not get the Import button. Grant Import Products explicitly.
2. The three steps
| Step | What happens |
|---|---|
| 1 · Upload | Download the template, fill it, drop the file |
| 2 · Preview | The file is parsed and shown back before anything is written |
| 3 · Run | Rows are created; the job reports per-row results |
Nothing is written until Run. Preview is a genuine dry run.
3. The column contract
Stated verbatim on the screen:
| Column | Required | Notes |
|---|---|---|
name | ✅ | The product name |
slug | ✅ | Public URL fragment. Must be unique |
base_price | ✅ | Numeric |
description | — | |
is_publishable | — | Drives the STORE badge |
uom_code | — | Must match an existing unit code, e.g. KG |
uom_code must already existThe importer matches on the unit code, not its name. A row citing a code you have not created fails — so run the import after Units of measure is populated, not before.
Use Discover on the units screen if you are importing data that already uses codes.
Maximum 500 rows per run. Split larger catalogues into batches.
4. What the importer does not do
| Not imported | Do it |
|---|---|
| Variations, SKUs, per-variation price | By hand in the editor, or via the external API |
| Bills of material | In the editor |
| Category assignment | Bulk Edit on the catalogue, after import |
| Tax category | Bulk Edit, or per product |
| Images | Storefront's bulk image upload (Allow Bulk product Image Upload) |
| Attribute value bindings | In the editor |
The template has no variation columns, so imported products arrive with no variations — and a product with no variation cannot be bought. Import creates the catalogue skeleton; variations are a second pass.
5. The admin contract
| Must be true | Or else |
|---|---|
| A project is selected | The import has no scope |
The role holds products.import | The button is absent |
Every uom_code exists | Those rows fail |
Every slug is unique | Those rows fail |
6. Downstream
| After import | Then |
|---|---|
| Products exist with a base price | Add variations before anything can be sold |
is_publishable set | The STORE badge shows, but with no variation there is nothing to buy |
| Job record kept | Re-openable to review per-row results |
7. Troubleshooting
| Symptom | Cause |
|---|---|
| No Import button | The role lacks products.import |
Rows rejected on uom_code | The code does not exist, or the name was used instead of the code |
Rows rejected on slug | Duplicate slug within the project |
| File refused | More than 500 rows |
| Products imported but not sellable | No variations — see §4 |
| Preview looks right, Run does less | Check the per-row results on the job; failures are reported per row, not as one error |