How to Import Products to WooCommerce with a CSV
Export a sample first and use its column headers. Most failed imports are a malformed file, not a broken importer — and variations need their parent rows to exist first.
Start by exporting. Create one product of each type you need by hand, then use Products → All Products → Export to produce a CSV. Its headers are exactly what the importer expects, and building your file from that template avoids most of the problems below.
The columns that matter
| Column | Notes |
|---|---|
ID |
Leave empty for new products |
Type |
simple, variable, variation, grouped, external |
SKU |
Unique; the key used for updates |
Name |
Required |
Published |
1 published, 0 private, -1 draft |
Regular price |
Numbers only — no currency symbol |
Sale price |
Optional |
In stock? |
1 or 0 |
Stock |
Quantity, if managing stock |
Categories |
Parent > Child, comma-separated for multiple |
Tags |
Comma-separated |
Images |
Full URLs, comma-separated; the first is the featured image |
Attribute 1 name / Attribute 1 value(s) |
Values separated by , |
Attribute 1 visible |
1 to show in the product details |
Attribute 1 global |
1 for a global attribute taxonomy |
Parent |
For variations: the parent SKU |
Two formatting rules cause most failures: prices must be plain numbers using the decimal separator WooCommerce expects, and the file must be UTF-8 encoded. Spreadsheets that save as UTF-8 with a byte-order mark, or in a regional encoding, produce mangled characters and unmatched headers.
Variable products and variations
Variations are separate rows that reference their parent:
Type,SKU,Name,Parent,Attribute 1 name,Attribute 1 value(s),Regular price
variable,SHIRT,Cotton Shirt,,Size,"Small, Medium, Large",
variation,SHIRT-S,,SHIRT,Size,Small,29.00
variation,SHIRT-M,,SHIRT,Size,Medium,29.00
variation,SHIRT-L,,SHIRT,Size,Large,32.00
Rules that are not optional:
- The parent row lists all possible values; each variation lists one.
- Variations reference the parent by SKU in the
Parentcolumn. - The parent must be imported first — keep the rows in this order, or import parents and variations as two separate files.
- Every variation needs a price, or the product will not be purchasable, as product variations explains.
Run the import
- Products → All Products → Import.
- Choose the file and tick Update existing products if you are updating rather than adding.
- On the column mapping screen, check every mapping. Anything set to "Do not import" that should be mapped is a silent data loss.
- Run the importer and read the summary: imported, updated, skipped, failed.
Do not close the tab. The importer processes in batches over AJAX, and closing it stops the run partway.
Updating existing products
The importer matches on ID first, then SKU. A file containing only SKU and Regular price updates just the prices and leaves everything else untouched — which makes bulk price changes straightforward.
Always back up before an update run, per how to back up a WordPress site. An update import with a mismapped column can overwrite hundreds of descriptions in one pass, and there is no undo.
Images
The importer downloads each URL and adds it to the media library. Failures are common:
- URLs must be publicly reachable — a staging site behind a password will not serve them;
- the server must allow outbound HTTP requests;
- large images can exhaust PHP memory or time out, so raising the memory limit may be necessary;
- images already in the media library can be referenced by filename rather than URL, which is much faster.
For a large catalogue, upload the images to the uploads directory first and reference them by filename. It avoids thousands of HTTP downloads during the import.
When the import fails
| Symptom | Cause |
|---|---|
| Stops partway with no error | PHP timeout or memory — import in smaller files |
| "Invalid file type" | Not saved as CSV, or wrong delimiter |
| Mangled accented characters | File not saved as UTF-8 |
| Products imported as drafts | Published column set to -1 or missing |
| Variations without a parent | Parent row missing, or ordered after the variations |
| Prices ignored | Currency symbols or thousands separators in the price column |
| Categories not created | Wrong hierarchy syntax — use Parent > Child |
Split large files into batches of a few hundred rows. It makes failures easier to isolate and avoids timeouts entirely.
After importing
- Spot-check ten products in the editor, not just the catalogue listing.
- Confirm variable products show an add-to-cart form and a price.
- Check category assignments and images.
- Verify stock status, especially if the catalogue hides out-of-stock items.
- Purge caches, since archive pages will be stale — see how to clear the WordPress cache.
If products imported but do not appear on the shop page, the causes are catalogued in WooCommerce products not showing.
Frequently asked
- Import the parent as type 'variable' with its attributes, then the variations as type 'variation' referencing the parent SKU. The parent must exist before its variations are processed.
- Yes. Tick 'Update existing products' during import and match on SKU or ID. Only the columns present in the file are changed, so a partial update file is safe.
- The importer downloads images from the URLs in the file, which fails if the URLs are unreachable, the server blocks outbound requests, or PHP times out on large files.