Skip to main content

How to prepare a CSV file for import

The CSV import accepts two file layouts: "rows" (one metafield per row) and "columns" (one resource per row, one column per metafield). This page explains how to build a file in each of them so that it's mapped automatically and imported without errors.

General recommendations​

  • Start from an export. The easiest way to get a correct file is to export a few resources in the format you want, edit the values, and import the file back. Turn on Export empty metafields to get a ready-made template with placeholders for metafields that don't have values yet.
  • One resource type per file. Products, variants, collections, customers, etc. are imported separately - pick the resource type on the first step of the import.
  • Identify resources by a stable value. A handle, SKU, barcode, email, or GID - whichever you map as the resource identifier. Every row must have it.
  • Column headers are optional. The headers recommended below only let the import map the columns automatically. If the file has no header row or uses other names, that's fine - just pick what each column contains during the mapping step.
  • Save the file as UTF-8 CSV. Excel, Google Sheets, and Numbers all offer it in their export options; it keeps non-Latin characters intact.
  • Keep values in the recommended formats when you can: a dot for decimals (19.99), dates as YYYY-MM-DD, lists as JSON arrays (["Red","Blue"]). The import understands many other ways of writing a value, but the recommended ones are never ambiguous. See Metafield value formats for CSV import for every type.
  • Empty cells don't change anything unless the Empty metafields option is set to Delete.
  • Test on a few rows first. Import a small part of the file and check the import report - its Warning column explains every rejected value and every value the import had to interpret.

The "rows" format​

Each row holds one metafield of one resource: the resource identifier, the metafield's namespace, key, type, and value. A resource with three metafields takes three rows.

When to use it: files generated by scripts or other systems, metafields of many different types, and data where most resources have only a few of the possible metafields filled in.

Recommendations:

  • To have the columns mapped automatically, use these headers: Product handle (or another identifier, such as Product GID), Metafield namespace, Metafield key, Metafield type, Metafield value.
  • Fill in the namespace, key, and value in every row. The type is read from the Metafield type column, so it can differ from row to row.
  • The type is optional. If it's empty (or there's no Metafield type column at all), the type is taken from the metafield's definition or metafield set; if there's neither, multi_line_text_field is used. Fill it in for metafields without a definition. For a metafield with a definition, the definition's type is always used: a different or unknown type in this column is replaced and noted in the Warning column of the import report. Some types (id, metaobject_reference, mixed_reference) can't be imported without a definition at all.
  • Repeat the resource identifier on every row of the same resource - rows aren't grouped by anything else.

Example - two metafields for two products:

Product handleMetafield namespaceMetafield keyMetafield typeMetafield value
classic-cotton-teecustommaterialsingle_line_text_fieldCotton
classic-cotton-teecustomweightweight0.2 kg
wool-sweatercustommaterialsingle_line_text_fieldMerino wool
wool-sweatercustomweightweight0.45 kg

The "columns" format​

Each row holds one resource, and each metafield has its own column. This is how a spreadsheet usually looks, so it's the easiest format to edit by hand.

When to use it: editing data in Excel, Google Sheets, or Numbers, and files where most resources have the same set of metafields.

Recommendations:

  • To have the metafield columns mapped automatically, name each of them as ["namespace","key"], for example ["custom","material"]. You can put a readable name before it - Material ["custom","material"] - but keep the bracketed part exactly as is: that's how the import recognizes the metafield and the "columns" format. With any other header, select the "columns" format and set the namespace and key of each column manually during the mapping step.
  • A column has a single type, chosen during the mapping step. If the metafield has a definition or is part of a metafield set, the type is picked up automatically; otherwise, set it manually for each column. Creating definitions before the import saves you this step.
  • Every value in a column must fit that column's type.
  • Put the resource identifier in a separate column, such as Product handle, and use one row per resource. Leave a cell empty if a resource has no value for that metafield.

Example - the same data as above:

Product handleMaterial ["custom","material"]Weight ["custom","weight"]
classic-cotton-teeCotton0.2 kg
wool-sweaterMerino wool0.45 kg
Value formats

In both examples, the weight is written as 0.2 kg - the import converts it to the format Shopify stores ({"value":0.2,"unit":"KILOGRAMS"}), and both ways are accepted. For the formats of every other type - numbers, dates, references, lists, and more - see Metafield value formats for CSV import.