Preparing your CSV
ImportKit is deliberately relaxed about your file: any column names, any column order, extra columns welcome. There are a handful of things it does care about, and they're all on this page.
Every import type has a Download template button on the upload step, with a correct header row and worked example rows. Editing a template is faster and less error-prone than building a file from this page.
The format
| Requirement | Detail |
|---|---|
| File type |
.csv only. Not .xlsx, .xls,
.tsv, .json or .txt — the upload is
rejected before it's read. Exporting a
CSV from a spreadsheet →
|
| Delimiter | Comma. Semicolon and tab-separated files won't parse into columns correctly — see common problems. |
| Encoding | UTF-8. Anything else risks accented characters, currency symbols and quotes arriving mangled. |
| Header row | The first row must be the header row. No title row, no blank row, no merged cells above it. |
| Header names | Anything you like. Mapping is explicit, so names never need to match a Shopify field. They do need to be non-empty, and unique names make the mapping step much easier to read. |
| Column order | Irrelevant. |
| Extra columns | Fine. Set them to Ignore, or just leave them unmapped — either way their contents are dropped before the import runs and never reach Shopify. |
| Empty rows | Skipped automatically, including trailing blank rows your spreadsheet added. |
| Line endings | Windows, Mac or Unix all work. |
Quoting: commas, quotes and line breaks in values
Standard CSV quoting applies, and it matters more than people expect because HTML bodies and descriptions are full of commas.
- A value containing a comma must be wrapped in double quotes.
- A value containing a line break must be wrapped in double quotes. Multi-line values are fine.
- A double quote inside a quoted value is written twice:
"".
title,body_html,tags
Simple title,<p>No commas here</p>,guides
"A title, with a comma","<p>Wash cold, dry flat.</p>","guides, care"
Quotes inside,"<p>She said ""hello"" loudly.</p>",guides
Multi-line body,"<p>First paragraph.</p>
<p>Second paragraph.</p>",guides
Every spreadsheet application does this for you automatically when it saves as CSV. You only need to think about it if you're generating the file by hand or from a script.
How cells are treated
- Whitespace is trimmed
-
Leading and trailing whitespace is removed from every value, so
" PRODUCT "and"PRODUCT"behave identically. Copy-paste artefacts are harmless. - Blank cells are skipped, not written
- A blank cell means “don't set this field”, not “set it to empty”. This has a consequence worth remembering: you cannot clear an existing value by blanking the cell. To empty a metafield, delete it in the Shopify admin.
- Unmapped and ignored columns are dropped early
- They're removed before the row reaches the importer, so their contents are never sent to Shopify and never stored. Exporting a sheet with thirty columns of internal notes is safe.
Value formats by field type
Simple types are just what they look like. The structured types Shopify uses need a specific shape, and this is the list. These formats apply to metafield values and metaobject entry fields alike.
Text and numbers
| Type | Cell contents |
|---|---|
single_line_text_field | Example text |
multi_line_text_field | Plain text. Wrap in quotes to include real line breaks. |
number_integer | 10 |
number_decimal | 10.5 |
boolean | true or false |
date | 2026-01-31 (ISO 8601) |
date_time | 2026-01-31T12:30:00 |
url | https://example.com |
color | #4B0082 |
json | {"key":"value"} |
Structured types
These expect a small JSON object. Remember to quote the cell, because it contains commas.
| Type | Cell contents |
|---|---|
money | {"amount":"5.99","currency_code":"USD"} |
rating | {"value":"4.5","scale_min":"1.0","scale_max":"5.0"} |
weight | {"value":2.5,"unit":"kilograms"} |
dimension | {"value":25,"unit":"centimeters"} |
volume | {"value":20,"unit":"milliliters"} |
Rich text
Shopify stores rich text as its own JSON structure, which nobody wants to type into a spreadsheet. ImportKit converts for you, accepting any of three inputs:
- Plain text. Blank lines become separate paragraphs; single newlines stay as line breaks within a paragraph.
- HTML. A cell that looks like HTML is passed through inside a paragraph without being escaped.
- Shopify rich text JSON. Recognised and passed through untouched, byte for byte — so a value you exported from Shopify survives a round trip.
An empty cell produces an empty rich text document rather than an error.
Lists
Any list.* type accepts either a separated cell or a JSON array.
The separator rule is worth reading twice:
| Cell | Becomes | Why |
|---|---|---|
Waterproof, Lightweight, Recycled |
["Waterproof","Lightweight","Recycled"] |
No line breaks present, so commas are the separator. Items are trimmed. |
| A cell with real line breaks in it | One item per line | If the cell contains a line break, newlines become the separator and commas are kept inside items. This is how you store values that contain commas. |
["a","b"] |
["a","b"] |
Already a JSON array, so it's passed through as-is. |
a,,b, |
["a","b"] |
Empty items from doubled or trailing separators are dropped. |
| Empty cell | nothing written | Blank cells are skipped entirely. |
References
A reference points at another object in your store. What a cell can contain depends on the type — see Import references for the full treatment.
| Type | Cell contents |
|---|---|
product_reference | gid://shopify/Product/123 |
variant_reference | gid://shopify/ProductVariant/123 |
collection_reference | gid://shopify/Collection/123 |
page_reference | gid://shopify/Page/123 |
file_reference | gid://shopify/MediaImage/123 |
metaobject_reference | An entry handle such as jane-doe, or a full gid://shopify/Metaobject/123 |
For list.product_reference, bare numeric IDs are converted to
GIDs for you. For every other reference list type — collections,
variants, pages, files — a bare ID is sent as-is and Shopify rejects it. Use
full gid://… values in those lists.
Size limits
| Import | Pre-import check | |
|---|---|---|
| Maximum rows | 1,000,000 | 50,000 |
| Maximum file size | 50 GB | 32 MB |
Both limits can be raised on request. Email support@importkit.app with the volume you're working with — 50 GB is a default, not a hard ceiling.
The import path reads your file as a stream, so memory use doesn't grow with file size. The pre-import check can't stream — it has to see every row at once to detect duplicates across the whole file and total the credits needed — so it has a much lower cap.
If your file is over the check's limits, you'll get a “This file is too large to preview” notice and the import is still allowed. You lose the preview, not the safety: every row is still checked against your store as it's imported, and your conflict mode is applied per row in exactly the same way.
Over the import limits, the upload is refused with a message telling you to split the file. The size check runs as bytes arrive, so an oversized file is never pulled into memory.
A file can be well inside our limits and still contain a cell Shopify refuses — most
metafield values cap at 64 KB, and any list.* value at 128 items.
The pre-import check measures both, so you'll see it before importing rather than as
a failed row. Shopify's limits →
Splitting a large file
Rows are independent, so splitting is safe. Copy the header row into each part, and import the parts one after another. If you're splitting metafield values, keep all rows for the same resource together where you can — it makes the results easier to read, though nothing breaks if you don't.
A practical reason to split even when you don't have to: a 50,000-row file gets you a pre-import check, and a 200,000-row file doesn't.
Common problems
- Semicolons instead of commas
- Excel on a European locale saves CSVs with semicolons. The file will upload but you'll see one enormous column instead of several. Fix: use “CSV UTF-8 (Comma delimited)” on export, or change your regional list separator.
- Accented characters arriving as gibberish
-
Caféturning intoCafémeans the file wasn't saved as UTF-8. Re-export it with UTF-8 encoding. - Smart quotes and en dashes
-
Word processors substitute typographic characters. They import fine as text, but
they'll break a JSON cell —
{“amount”:“5.99”}with curly quotes is not valid JSON. Turn off autocorrect, or build JSON cells in a plain text editor. - Long numeric IDs turning into
1.23457E+12 - Spreadsheets convert long numbers to scientific notation and silently lose digits. Before pasting IDs, format the column as Text. This also protects SKUs and handles with leading zeros.
- A title row above the headers
- “Product export — March” in row 1 makes ImportKit read that as your header row. Delete it so the real headers are first.
- Duplicate header names
-
Two columns both called
valueare hard to tell apart on the mapping step. Rename one — it costs nothing, since names are arbitrary anyway. - Merged cells
- Merged cells don't survive a CSV export. Unmerge them and repeat the value on each row.
- An empty header row
- A file whose first row is blank has no columns to map, and ImportKit says so rather than guessing.
- Nothing to import
- A file with only a header row and no data rows is rejected with an explanation.
The drop zone with its limits shown
The upload step's drop zone including the “Accepts .csv files up to 50 GB and 1,000,000 rows” hint underneath it.
assets/screenshots/drop-zone.png