Guide

How to Import Products into Shopify with a CSV File: A Complete Guide

Last updated: 3 May 2026

If you need to add many products to your Shopify store, doing it one product at a time gets painful fast. A CSV file lets you import dozens, hundreds or thousands of products in a single upload.

A CSV (comma-separated values) file is just a spreadsheet. Each row is a product - or a variant of a product - and each column holds a field like the title, price, SKU or inventory level.

Merchants typically reach for CSV imports when they:

  • Move products from another platform like WooCommerce, BigCommerce or Magento
  • Add a supplier's product list to their store
  • Update prices, stock or barcodes in bulk
  • Restructure their catalog after a vendor change
  • Onboard a new store with thousands of SKUs

In this guide you'll learn:

  • How Shopify's built-in CSV importer works, step by step
  • The exact CSV format Shopify expects, column by column
  • How variants, images, inventory and metafields work in the CSV
  • The most common reasons CSV imports fail - and how to fix each one
  • When the native importer is enough and when you need an app

Let's start with the two paths.

Two Ways to Import a CSV into Shopify

There are two ways to get products into Shopify from a CSV:

1. Shopify's built-in CSV importer. Free, included in every Shopify plan, available at Products -> Import in your admin. Works well when your file already follows Shopify's exact format.

2. A CSV import app. Apps like Simple CSV Import let you import almost any CSV file by mapping its columns to Shopify fields. Useful when your file came from a supplier, an old store or anywhere that doesn't follow Shopify's structure.

We'll cover the native importer first, including the exact format it expects and the most common things that go wrong. If you finish that section and your CSV still won't import, the second half of the guide explains the alternative.

How Shopify's Native CSV Importer Works

You can find Shopify's CSV importer in your admin under Products -> Import.

Shopify admin product import dialog for uploading a CSV file
The Shopify CSV importer is available in Products -> Import.

Click Import, upload a CSV file in Shopify's exact format and Shopify will create or update products based on the file's contents.

It's free, it's built in and for the right file it works fine. But it has real limits worth knowing before you commit:

  • No column mapping. Your CSV must use Shopify's exact column names. product_name won't be recognized as a title - it has to be Title.
  • No remote URLs. You can only upload a file from your computer. You can't point Shopify at a supplier's URL or an FTP feed.
  • No scheduling. Every import is manual. There's no way to run a daily or hourly sync.
  • No preview. You upload, Shopify processes and then you see what happened.
  • Strict format requirements. A small mistake - a missing handle, a stray quote, a comma inside a title - can cause rows to silently fail.
  • File size and row limits. Large catalogs may need to be split into multiple files.

For a clean, Shopify-formatted file under a few thousand rows, the native importer is the simplest tool for the job. For anything else, an app will save you hours.

The Shopify Product CSV Format: A Complete Column Reference

Shopify's product CSV has more than 50 possible columns. You don't need every one - most imports use 10 to 15 - but you do need to use Shopify's exact names. Here's what each group of columns does.

You can download Shopify's official template here: Shopify product CSV template.

Identity columns

These describe what the product is.

  • Handle - A unique identifier used in the product's URL (e.g., red-cotton-shirt). Required. All variants of the same product must share the same Handle.
  • Title - The product name shown to shoppers.
  • Body (HTML) - The product description. Supports HTML.
  • Vendor - The brand or manufacturer.
  • Product Category - Shopify's standard product taxonomy.
  • Type - A custom product type used for organization.
  • Tags - Comma-separated tags. Useful for filtering and collections.
  • Published - TRUE or FALSE. Controls whether the product is visible on your storefront.
  • Status - active, draft or archived. Imports default to active unless you specify otherwise.

Variant columns

Variants are different versions of the same product - sizes, colors, materials.

  • Option1 Name / Option1 Value - e.g., Size / Medium
  • Option2 Name / Option2 Value - e.g., Color / Blue
  • Option3 Name / Option3 Value - Up to three options per product
  • Variant SKU - Unique stock keeping unit
  • Variant Grams - Weight in grams (always grams, regardless of unit)
  • Variant Inventory Tracker - shopify, a third-party fulfillment service name or blank
  • Variant Inventory Qty - Stock level
  • Variant Inventory Policy - deny (don't allow oversell) or continue (allow oversell)
  • Variant Fulfillment Service - manual for self-fulfillment or a service name
  • Variant Price - Selling price
  • Variant Compare At Price - "Was" price for showing discounts
  • Variant Requires Shipping - TRUE or FALSE
  • Variant Taxable - TRUE or FALSE
  • Variant Barcode - UPC, EAN, ISBN or other barcode
  • Variant Weight Unit - g, kg, oz or lb
  • Variant Tax Code - Used with Avalara
  • Cost per item - Your cost (used for margin reporting, not shown to customers)

Image columns

  • Image Src - Public URL of the product image
  • Image Position - 1, 2, 3... controls the order images appear
  • Image Alt Text - Accessibility and SEO text
  • Variant Image - A specific image to display when this variant is selected

SEO columns

  • SEO Title - Title used in search engines
  • SEO Description - Meta description for search engines

Other columns

  • Gift Card - TRUE if the product is a gift card
  • Google Shopping / * - A series of fields for Google Shopping feeds
  • Variant Country/Region of Origin - ISO country code
  • Included / [country] - TRUE or FALSE per market
  • Price / [country] - Market-specific price
  • Compare At Price / [country] - Market-specific compare-at price

Metafield columns

  • Metafield: namespace.key [type] - Any custom data field. We'll cover this in detail below.

Watch out: The columns merchants get wrong most often are Variant Inventory Tracker (must be shopify to track stock), Status (default to active if you want products visible immediately), Image Position (controls image order) and the market-specific Price columns (only needed if you sell in multiple markets).

How Variants Work in the CSV

Variants are where most CSV imports go sideways. Once you understand the pattern, it stops being mysterious.

Shopify treats every variant as its own row in the CSV. Variants of the same product are tied together by sharing the same Handle. Only the first row of a product needs the full product data (Title, Body, Vendor, Tags, etc.). Subsequent variant rows can leave those columns blank - Shopify uses the Handle to know they belong to the same product.

Here's a T-shirt in three sizes and two colors (six variants):

Handle,Title,Option1 Name,Option1 Value,Option2 Name,Option2 Value,Variant SKU,Variant Price
classic-tee,Classic Tee,Size,Small,Color,Blue,TEE-S-BLU,29.99
classic-tee,,Size,Medium,Color,Blue,TEE-M-BLU,29.99
classic-tee,,Size,Large,Color,Blue,TEE-L-BLU,29.99
classic-tee,,Size,Small,Color,Red,TEE-S-RED,29.99
classic-tee,,Size,Medium,Color,Red,TEE-M-RED,29.99
classic-tee,,Size,Large,Color,Red,TEE-L-RED,29.99

Notice that only the first row has the title. The rest are variant rows.

Two rules to remember:

  1. All variants of one product share one Handle. Lose the handle and Shopify creates duplicate products instead of variants.
  2. Variant order matters for the default selection. The first row is the default variant shown to shoppers.

If you want a specific image to appear when a shopper selects a variant - for example, the red shirt photo when "Red" is chosen - fill in the Variant Image column with that image's URL.

How Images Work in the CSV

Images are the second-biggest source of import failures. Three things to know:

1. Image Src must be a public URL. Shopify needs to fetch the image from your URL. If the image sits behind authentication, hotlink protection or a private CDN, Shopify can't download it. Test a URL by opening it in a private browser window - if it loads, Shopify can fetch it.

2. Multiple images use multiple rows. A product with three images uses three rows: one with all the product data plus the first image URL, then two more rows with the same Handle, blank product data and only the image columns filled.

Handle,Title,Image Src,Image Position
red-shirt,Red Shirt,https://example.com/shirt-1.jpg,1
red-shirt,,https://example.com/shirt-2.jpg,2
red-shirt,,https://example.com/shirt-3.jpg,3

3. Format and size matter. Shopify accepts JPG, PNG, GIF and WebP. It does not support .avif or .bmp. Files larger than 20 MB or with unusual color profiles can also fail. If your CSV has AVIF or BMP images, convert them to WebP or JPG before importing.

A few real-world image gotchas:

  • Shopify's image fetcher can be aggressive and time out on slow servers
  • URLs that redirect (e.g., http:// -> https://) sometimes fail mid-fetch
  • Expired or signed CDN URLs (those with ?expires=... parameters) often stop working before the import finishes
  • Hotlink protection on the source server will block Shopify entirely

If you're seeing images fail in bulk, the source URLs are almost always the problem.

Inventory and Locations

Shopify supports multi-location inventory - you can stock the same SKU at multiple warehouses, retail stores or 3PLs. The native CSV importer doesn't handle this well.

A standard product CSV can only set inventory for one location: your store's default location. If you need to set inventory across multiple locations, you have three options:

  1. Import the products via CSV with inventory at the default location, then move stock with Shopify's bulk editor
  2. Use Shopify's separate inventory CSV export/import (Inventory -> Export, edit, Import)
  3. Use a CSV import app that supports multi-location inventory in a single file

For setting inventory at the default location during import, two columns matter: Variant Inventory Tracker (set to shopify to track stock) and Variant Inventory Qty (the quantity).

If Variant Inventory Tracker is blank, Shopify won't track inventory for that variant at all - and the quantity you set will be ignored. This is one of the most common "I imported my products but inventory is zero" problems.

Metafields in the CSV

You can import metafields directly through the product CSV. The column header uses this format:

Metafield: namespace.key [type]

Examples:

  • Metafield: custom.material [single_line_text_field] - a fabric or material name
  • Metafield: custom.warranty_years [number_integer] - a warranty duration
  • Metafield: my_fields.care_instructions [multi_line_text_field] - a care guide

Type values match Shopify's metafield types: single_line_text_field, multi_line_text_field, number_integer, number_decimal, boolean, date, url and others. The metafield definition must already exist in your store before the import - Shopify won't create new definitions automatically.

Step-by-Step: Importing with the Native Importer

Once your CSV is in the right format, the actual import is straightforward.

Before you start: pre-import checklist

  • File is saved as .csv with UTF-8 encoding
  • All required columns are present (Handle, Title at minimum)
  • All Image Src URLs are publicly accessible
  • Variants share Handles correctly
  • Test on a small file first (5-10 rows)
  • Backup your store data - once an import runs, undoing it row by row is brutal

Step 1 - Download the template

Get Shopify's official template. Even if you have your own CSV, opening the template helps you see the exact column names Shopify expects.

Step 2 - Add or paste your data

Open the template in Excel, Google Sheets, LibreOffice or Numbers. Add your products. Each row is a product or a variant.

Step 3 - Save as CSV with UTF-8 encoding

Export or save as a CSV file. Use UTF-8 encoding - without it, special characters (accents, em dashes, currency symbols) become question marks in your store. We'll cover the per-tool instructions in the next section.

Step 4 - Upload to Shopify

In your Shopify admin:

  1. Go to Products
  2. Click Import
  3. Choose your CSV file
  4. Optionally select Overwrite any current products that have the same handle (use carefully)
  5. Click Upload and continue, then Start import

Step 5 - Wait for the confirmation email

Shopify processes the import in the background. You'll get an email when it's done - usually within a few minutes for small files, longer for large ones.

Step 6 - Verify and check for errors

Open Products in your admin. The email also flags any rows that failed. Click through to a few products and confirm titles, variants, prices and images all look right. If something's off, check the troubleshooting section below before re-importing.

Excel and Google Sheets Pitfalls

Spreadsheet software is helpful, until it isn't. Here are the most common ways Excel and Google Sheets quietly break your CSV.

Scientific notation on barcodes. A 13-digit barcode like 1234567890123 becomes 1.23457E+12 and Shopify gets a useless number. Fix: before pasting, format the barcode column as Text. In Excel: select column -> right-click -> Format Cells -> Text. In Google Sheets: select column -> Format -> Number -> Plain text.

Leading zeros stripped from SKUs. A SKU like 00123 becomes 123. Same fix - format the column as Text first.

Date auto-formatting. A SKU like 1-2-3 becomes a date. Same fix.

Long URLs broken into formulas. If a URL starts with =, Excel treats it as a formula. Rare, but it happens.

UTF-8 vs Windows-1252 encoding. Excel on Windows defaults to Windows-1252, which mangles non-English characters. Fix: when saving, choose "CSV UTF-8" (it's a separate option in modern Excel). Google Sheets exports UTF-8 by default - one of its advantages here.

Comma vs semicolon delimiter. In many European locales, Excel saves CSV files with semicolons (;) instead of commas. Shopify expects commas. Fix: in Excel, change your locale temporarily or use Google Sheets which always exports with commas.

BOM markers. Some Excel exports add a hidden Byte Order Mark to the start of the file. Shopify usually handles it, but other tools may not.

Line breaks inside Body (HTML). Long descriptions with embedded line breaks need to be wrapped in double quotes, with internal quotes escaped as "". Easier to write descriptions as a single line of HTML or paste from a tool that handles escaping.

If your import is producing weird characters, scientific notation or missing rows, the spreadsheet is almost always the cause - not Shopify.

Troubleshooting Common Shopify CSV Import Errors

Most CSV import failures fall into a small set of patterns. Here's what each one means and how to fix it.

"The file you uploaded is too large"

Shopify limits CSV imports by file size. Split the file into smaller chunks (most merchants use 5,000 rows per file as a safe limit) and import them one at a time.

"Invalid CSV header" / missing required columns

Your column names don't match what Shopify expects. The most common culprits: lowercase handle instead of Handle, Variant Sku instead of Variant SKU or Image URL instead of Image Src. Open Shopify's template and copy the headers exactly.

"Image source is required" / "Could not be downloaded"

The Image Src URL isn't accessible to Shopify. Check that the URL loads in a private browser window. If it does and Shopify still can't fetch it, the source is likely blocking Shopify's user agent or rate-limiting requests.

Images time out during import

Shopify's image fetcher gives up after a few seconds per image. If your images are hosted on a slow server, many will fail. Move the images to a fast public host first (Cloudinary, Imgur, Dropbox public links) or use an app that downloads the images on its own server first and re-uploads them to Shopify.

"Duplicate handle" errors

Two different products share the same Handle. Check your file - if you intended them to be variants, the variant rows should have blank product fields and the same Handle. If they're separate products, give each a unique Handle.

Variants didn't import - they merged into one product

The Handle column is identical across rows that should be different products. Add unique Handles to each.

Products imported but show 0 inventory

The most common cause: Variant Inventory Tracker is blank instead of shopify. Without that value, Shopify ignores the inventory quantity. Re-export with the column set to shopify for trackable items.

Products imported but show as Draft (not visible on storefront)

The Status column is set to draft or the Published column is FALSE. Set Status to active and Published to TRUE if you want products live immediately.

Special characters became question marks

Encoding issue. Save the CSV as UTF-8 (specifically "CSV UTF-8" in Excel) and re-import.

A comma in a product title broke the row

A comma inside a field - e.g., Title: Shoes, Black, Size 10 - splits the row into multiple cells. Wrap any field containing a comma in double quotes: "Shoes, Black, Size 10". Most spreadsheet tools do this automatically when saving as CSV.

Import "succeeded" but some products are missing

Open the email Shopify sent - it usually flags skipped rows. Common reasons: invalid handles, blank required fields, image fetch failures or duplicate SKUs colliding with existing products. Fix those rows and re-import only the missing ones.

When the Native Importer Isn't Enough

The native importer is a good tool, but several common situations push merchants past what it can do:

  • Your CSV came from a supplier, not Shopify. Renaming and re-ordering 30 columns by hand for every weekly update is not a sustainable workflow.
  • You need column mapping. A CSV with columns named name, cost and qty won't be recognized - it has to be Title, Variant Price and Variant Inventory Qty.
  • You need to import from a URL. Suppliers often provide a feed at a URL that updates automatically. The native importer can only handle a file from your computer.
  • You need scheduled imports. Daily price updates, hourly inventory syncs - none of this is possible natively.
  • You need to update existing products, not just create new ones. The native importer can update products with matching Handles, but it can't match by SKU or barcode.
  • Your file is too big. Splitting and re-uploading a 50,000-row file every time is a chore.
  • You want a preview. Seeing what will happen before it happens saves a lot of cleanup.

If any of these sound familiar, an import app is worth considering. For a deeper look at updating existing products specifically, see our guide on how to bulk update Shopify products with CSV.

Importing with Simple CSV

Simple CSV Import is built specifically for the situations the native importer can't handle. It's free for files up to 100 rows, with paid plans for larger imports.

Here's how a typical import works.

Step 1 - Upload your CSV

Upload a file from your computer or paste a URL pointing to a supplier feed. URL imports are useful for any source that updates regularly.

Step 2 - Choose what you want to do

Pick whether the import should create new products, update existing ones or both. For updates, choose how products are matched: by SKU, barcode or product handle. SKU is the most reliable for supplier feeds.

Step 3 - Map your columns

Simple CSV reads your CSV's actual headers and lets you map each one to a Shopify field. Many fields are matched automatically - price to Variant Price, stock to Inventory Qty, name to Title - and you can adjust any mapping by hand.

Simple CSV column mapping interface for matching CSV headers to Shopify fields
Map any CSV column to Shopify product fields.

Step 4 - Preview the import

Before anything is changed in your store, you can preview how the products will look. This catches problems before they hit your live catalog.

Simple CSV product import preview screen before starting an import
Preview how your products will appear in Shopify before starting the import.

Step 5 - Run the import

Start the import and watch progress on the status page. You'll see how many products were created, updated and skipped - with reasons for any that failed.

For supplier feeds and recurring updates, the same setup runs on a schedule, so you can leave it alone and your store stays in sync.

Best Practices for CSV Imports

A few habits that save hours over time:

  • Always test with a small file first. 5-10 rows is plenty. Confirm everything imported correctly before running the full file.
  • Backup your store before any large import. A free backup app saves you when something goes sideways.
  • Match by SKU when updating, by Handle when creating. SKUs are stable across imports; handles are tied to URLs and shouldn't change.
  • Run imports outside peak hours. Imports use API calls and large imports can slow your storefront if they run during your busiest sales windows.
  • Save your import file with the date in the filename. When something goes wrong two weeks later, you'll want to know which import did what.

Guide FAQ

Frequently Asked Questions

Yes, but the CSV from the other platform won't match Shopify's format. You'll either need to manually restructure the file or use a migration app or CSV import app with column mapping. For full WooCommerce or PrestaShop migrations including orders and customers, a dedicated migration tool will save significant time.

Shopify's CSV import has a soft limit around 15 MB and a row limit that scales with plan. Most merchants split files to 5,000 rows or fewer to stay safely under the limit and avoid timeouts.

Yes. Use the column header format Metafield: namespace.key [type]. The metafield definition must exist in your store first - Shopify won't create new definitions during import.

Yes. Shopify's native importer matches by Handle. Apps like Simple CSV can also match by SKU or barcode, which is more reliable when handles have changed.

The most common causes are inaccessible URLs, unsupported formats like .avif and .bmp, files too large or source servers that block Shopify's image fetcher.

Check the import confirmation email - it lists skipped rows and the reason for each. Common causes: blank required fields, duplicate Handles, image fetch failures or duplicate SKUs colliding with existing products.

Not in the standard product CSV - that only sets inventory at your default location. For multi-location inventory, use Shopify's separate inventory CSV from Inventory -> Export or a CSV import app that supports it.

Not with the native importer. Apps like Simple CSV support scheduled imports from a URL, which is the standard way to handle supplier feeds that update regularly.

Excel converted long numbers into scientific notation when you saved the file. Format the barcode column as Text before entering or pasting data or open the file in Google Sheets which handles this better.

Yes. Use the Variant Image column to assign a specific image to a variant. The image still has to be referenced in the file's image rows under Image Src, but Variant Image tells Shopify which one to display when that variant is selected.

Ready to Import?

If your CSV file follows Shopify's exact format and your catalog is small to medium, the native importer is the simplest place to start. If your file came from a supplier, doesn't match Shopify's structure or you need scheduled or URL-based imports, Simple CSV Import is built for that. The free plan handles up to 100 rows, so you can try it on a real file before paying for anything.