- shopify
- csv
- products
- import
Shopify Product CSV: Complete Field Reference

Quick answer
A Shopify product CSV needs only a Title column to create a product. To update products or add variants, you also need URL handle, Option1 name, and Option1 value. Every other column is optional, and a blank cell can overwrite existing data when you import with "Overwrite products with matching handles" turned on.
Shopify's product CSV has dozens of columns, and a small mistake in one of them, like a misspelled header, a weight entered in kilograms, or a variant row missing its handle, can make an import fail or change the wrong data. This reference lists every column in Shopify's current product CSV format, what it accepts, and what happens when you leave it blank.
The details below come from Shopify's product CSV documentation. If you want a file with the headers already in place, the Shopify CSV Template generator builds one for simple products, size or color variants, and gift cards.
Which columns are required in a Shopify product CSV?
It depends on what the import does:
| Task | Required columns |
|---|---|
| Create a new product | Title |
| Create a product with variants | Title, URL handle, Option1 name, Option1 value |
| Update existing products | URL handle, Title |
| Update variant data such as SKU or weight | URL handle, Title, Option1 name, Option1 value |
The Option1 columns matter more than they look. Shopify matches variant data (SKU, weight, price) to variants through Option1 name and Option1 value. If you import variant columns without them, Shopify creates a new default variant and deletes the existing ones.
Product columns
These describe the product as a whole. On a product with several variants, fill them in on the first row only.
| Column | What it holds | Allowed values | Default if blank |
|---|---|---|---|
| Title | Product name shown to customers | Text | None (required to create) |
| URL handle | Unique ID used in the product URL | Lowercase letters, numbers, and hyphens; no spaces | Generated from Title (Black Sunglasses becomes black-sunglasses) |
| Description | Product description | Text or HTML | Blank |
| Vendor | Brand, manufacturer, or supplier | Text | Blank |
| Product category | Category from Shopify's standard taxonomy | Full breadcrumb (Home & Garden > Linens & Bedding > Bedding > Bed Sheets) or category ID (hg-15-1-2) | Blank |
| Type | Your own product grouping | Text | Blank |
| Tags | Keywords for search and filtering | Comma-separated, up to 250 per product | Blank |
| Published on online store | Visibility on the Online Store channel | true or false | true |
| Status | Product status | active, draft, or archived | active |
| Gift card | Marks the product as a gift card | true or false | false |
| SEO title | Title in search results | Up to 70 characters | Uses Title |
| SEO description | Meta description in search results | Up to 320 characters | Uses Description |
Variant columns
Each variant gets its own row. Every variant row repeats the URL handle, and you leave Title, Description, Vendor, and Tags empty on rows after the first.
| Column | What it holds | Allowed values | Default if blank |
|---|---|---|---|
| Option1 name / Option1 value | First option, for example Size / Small | Text | Blank; a product with no options gets one default variant |
| Option2 name / Option2 value | Second option, for example Color / Red | Text | Blank |
| Option3 name / Option3 value | Third option | Text | Blank |
| Option1 LinkedTo (and 2, 3) | Links an option to a category metafield | product.metafields.shopify.<attribute> | Blank |
| SKU | Stock keeping unit | Text; can't be blank if you use a custom fulfillment service | Blank |
| Barcodes | Up to 20 barcodes per variant | Semicolon-separated type:value pairs, such as gtin:00012345678905 | Blank |
| Price | Selling price | Number, no currency symbol | 0.00 |
| Compare-at price | Original price shown struck through | Number, no currency symbol | Blank |
| Cost per item | What the item costs you | Number, no currency symbol | Blank |
| Charge tax | Whether tax applies | true or false | true |
| Inventory tracker | Who tracks stock | shopify, shipwire, amazon_marketplace_web, or blank | Blank (not tracked) |
| Inventory quantity | Stock on hand, single-location stores only | Whole number | 0 |
| Continue selling when out of stock | Overselling rule | deny or continue | deny |
| Weight value (grams) | Variant weight | Whole grams, no unit or decimals (5.125 kg is 5125) | 0 |
| Weight unit for display | Unit shown to customers | g, kg, lb, or oz | kg |
| Requires shipping | Whether the item ships | true or false | true |
| Fulfillment service | Who fulfills the variant | manual, shipwire, webgistix, amazon_marketplace_web, or a custom service name in lowercase with dashes | manual |
| Variant image URL | Image for this specific variant | Public URL starting with https:// (or http://) | Blank |
Two limits trip people up. Inventory quantity only works for stores with one location; multi-location stores need Shopify's separate inventory CSV. And Barcodes replaced the older single Barcode column, so a file can't contain both.
Image columns
Images go one per row. For each extra image, add a row with the same URL handle and fill in only the image columns. A product can have up to 250 images.
| Column | What it holds | Allowed values | Default if blank |
|---|---|---|---|
| Product image URL | Link to the image file | Public URL starting with https:// (or http://) | Blank |
| Image position | Display order | Number, starting at 1 | Set automatically |
| Image alt text | Text for screen readers | Up to 512 characters (Shopify suggests about 125) | Blank |
Market and Google Shopping columns
| Column | What it holds | Allowed values | Default if blank |
|---|---|---|---|
| Included / [market name] | Whether the product sells in that market | true or false | true |
| Price / [market name] | Fixed price in that market's currency | Number | Blank |
| Compare-at price / [market name] | Fixed compare-at price for that market | Number | Blank |
| Google Shopping / Google product category | Google's product taxonomy | Breadcrumb or category ID | Blank |
| Google Shopping / Gender, Age group, MPN, Condition, Custom label 0 to 4 | Attributes for Google Shopping feeds | Varies by attribute | Blank |
How do metafield columns work?
Product metafields get one column each. The header is either product.metafields.<namespace>.<key> or a label followed by that path in parentheses, for example Fabric (product.metafields.custom.fabric). Shopify supports common types such as single_line_text_field, multi_line_text_field, number_integer, number_decimal, boolean, date, url, color, weight, money, and their list. versions.
Variant metafields aren't supported in the product CSV. Edit those in the bulk editor instead.
You can also add a Collection column on import to put each product into one collection. Shopify creates the collection if it doesn't exist. The column is import-only, so it won't appear in exports.
Why do some templates say "Handle" instead of "URL handle"?
Shopify renamed its CSV headers, and older templates still use the previous names. Shopify accepts the old names for backward compatibility but recommends the current format. The most common pairs:
| Older header | Current header |
|---|---|
| Handle | URL handle |
| Body (HTML) | Description |
| Published | Published on online store |
| Variant SKU | SKU |
| Variant Price | Price |
| Variant Compare At Price | Compare-at price |
| Variant Grams | Weight value (grams) |
| Variant Weight Unit | Weight unit for display |
| Variant Inventory Tracker | Inventory tracker |
| Variant Inventory Qty | Inventory quantity |
| Variant Inventory Policy | Continue selling when out of stock |
| Variant Fulfillment Service | Fulfillment service |
| Variant Requires Shipping | Requires shipping |
| Variant Taxable | Charge tax |
| Variant Barcode | Barcodes |
| Image Src | Product image URL |
| Image Alt Text | Image alt text |
| Variant Image | Variant image URL |
Whichever set you use, keep it consistent. Shopify's import page asks that headers match the sample file exactly, including case, so handle in lowercase won't work where Handle is expected.
What happens to blank cells when you overwrite products?
When you import with Overwrite products with matching handles selected, Shopify treats blanks and missing columns differently:
- A column that's in the file but left blank replaces the existing value with a blank.
- A column that isn't in the file at all leaves the existing value alone.
- Changing anything in Option1 value, Option2 value, or Option3 value deletes the existing variant IDs and creates new ones. Any app or report that stores variant IDs will need the new ones.
That makes a trimmed file the safest update: keep the handle, Title, and the columns you mean to change, plus Option1 name and Option1 value if you touch any variant field. If you import a full export instead, make it fresh, so older values in other columns don't overwrite recent edits in the admin. The same rule applies to bulk price edits and tag changes.
File format rules
- Save as UTF-8 with LF line endings.
- The first row must be the column headers.
- Separate values with commas. If you edit in Excel, check that the export uses commas and not semicolons.
- Keep the file under 15 MB.
- Link images by URL; you can't embed image files in a CSV.
If an import still fails, Shopify's common import issues page lists each error message and its fix.
Start from a working template
Building the header row by hand is where most typos creep in. The Shopify CSV Template generator gives you a file with the headers and sample rows for your product type, so you only replace the sample values. It uses the older header names listed above, which Shopify still accepts. It runs in your browser, and the file never leaves your computer.
If you edit your catalog in spreadsheets regularly, ShopSheets pulls your Shopify products straight into Google Sheets, so you can start from your real data instead of an empty template.