Ecommerce platforms

WooCommerce product imports that survive contact with reality

The CSV importer does exactly what the file tells it, which is the problem. How variations, SKUs, images and timeouts behave, and how to make an import you can safely run twice.

By Rehan Idrisi · · 7 min read

Part of: WooCommerce

An import that runs clean across ten test rows can still wreck a catalog at four thousand. Nothing about the mechanism changes between the two. What changes is that real supplier data contains duplicate SKUs, dead image URLs, half-specified variations and three spellings of the same category, and the importer has a defined behaviour for every one of those situations that is not always the behaviour you would have chosen.

The file describes three different kinds of row

WooCommerce's CSV importer reads a flat file where one line is one product record, and a type column decides what kind of record it is. A simple product is self-contained: one row, one SKU, one price. A variable product is a parent row that declares which attributes vary, and carries no price of its own. Each variation is then a separate row with its own SKU and price, pointing back at the parent by the parent's SKU. Get that reference wrong and the variations arrive as orphans or fail outright, leaving a product on the shop that nobody can buy.

Type,SKU,Name,Parent,Regular price,Attribute 1 name,Attribute 1 value(s)
variable,TSHIRT,Cotton T-Shirt,,,Size,"S, M, L"
variation,TSHIRT-S,,TSHIRT,499,Size,S
variation,TSHIRT-M,,TSHIRT,499,Size,M
variation,TSHIRT-L,,TSHIRT,549,Size,L

The parent has to list every value its variations use. A variation carrying a size the parent never declared has nothing to attach to.

SKU is the identity column, so treat it like one

WooCommerce enforces one SKU per product across the whole catalog, variations included. A row carrying a SKU that already exists gets refused on a fresh insert and reported as a failed row, instead of quietly creating a second copy. That behaviour is the one you want. Trouble starts with blank SKUs, or with the same SKU appearing twice because a supplier sheet listed a product under two names. Blank leaves the importer nothing to match on, so a second run inserts duplicates instead of updating what is already there. Every downstream system you will ever connect, from marketplace feeds to accounting to stock sync, keys on SKU as well. Deduplicate before the import, never after.

Updating and inserting differ by one checkbox

Run the same file twice without the update option enabled and every existing row errors. Enable it and the importer matches on ID first, then SKU, and overwrites the columns the file contains. The columns it does not contain are where people get caught. A file that omits a column leaves the stored value alone, so a two-column file of SKU and price is a safe way to reprice a catalog. A full supplier export with an empty description column is a different story, and can blank descriptions somebody spent a week writing. Read your own file column by column before pointing it at live products.

Images are fetched one URL at a time, by your server

The images column takes URLs separated by commas, the first becoming the featured image and the rest the gallery. Your server downloads each of those files in turn and writes them into the media library. Two things follow from that. Import time is bound by how quickly the other server responds, so a slow image host can stretch a small catalog into hours. And a URL that 404s raises an error against its row, so an import that looked finished can leave products with no image, or rows that never landed at all. Run a plain status check over the image URLs first. Finding out halfway through a long import costs far more than checking does.

Categories and attributes are created as a side effect

Any category path in the file that does not exist yet gets created during the import. Attribute values work the same way. This is convenient, and it is also how a catalog ends up with Mens, Men's and Men s sitting side by side, because three supplier files spelled it three ways. Nothing warns you. A typo deep in a hierarchy path silently builds a whole new branch. Normalise category and attribute spellings in the spreadsheet, where find and replace takes seconds, because unpicking them later means reassigning products by hand.

Why large imports stop halfway

The importer works through the file in batches across repeated background requests, so no single request has to process everything. Each batch still has to finish inside PHP's execution time and memory limits, and image downloads make the cost of a row unpredictable. A batch that exceeds either limit returns a server error and the run stops where it stopped. Rows before that point are in the database. Rows after it are not. Recovery means a smaller batch size and a re-run with updating enabled, which is painless only if the SKUs are clean, since SKU is what the re-run matches on.

The importer does exactly what the file says. Almost every corrupted catalog traces back to a file that was already wrong when it was uploaded.

Making an import repeatable

  1. Validate the file's structure before it goes near a server. Headers, row types, parent references and SKU uniqueness are all checkable up front.
  2. Import into a staging copy first, on a database you are happy to throw away.
  3. Start with a twenty-row slice of the real file, not a hand-typed sample. Supplier data carries encoding problems your sample never will.
  4. Import as drafts where the data allows it, review a handful of products, then publish in bulk.
  5. Export the catalog before every import. That export is your rollback.
  6. Keep the import file. Re-importing it with updating enabled is the quickest way to undo a bad bulk edit, and only possible if you still have it.

Most of the damage happens in the spreadsheet

  • Leading zeros stripped from SKUs and barcodes, because a spreadsheet read them as numbers.
  • Long numeric codes converted to scientific notation, which is unrecoverable once the file is saved.
  • Non-UTF-8 encoding turning product names into mojibake. Save as UTF-8 explicitly.
  • Semicolon delimiters produced by a regional spreadsheet setting, against an importer expecting commas.
  • Decimal commas in prices, which either fail the row or import as a very different number.
  • Unquoted line breaks inside a description, splitting one product across several rows.
  • Currency symbols and thousand separators in price columns, which belong in the display layer and not the data.

This site has an in-browser Product CSV Validator that checks a product CSV's structure and the common import errors before you upload it anywhere, and it runs entirely on your device, so a supplier's price list never leaves the machine. The SKU Generator helps when a file arrives with no SKUs at all and you need a consistent scheme across it. CSV to JSON and Line to CSV are useful for the earlier stage, when the data turns up in a shape no importer will accept.

What is the most common WooCommerce product import mistake?

Duplicate or missing SKUs. WooCommerce matches existing products by SKU when updating, so blank SKUs make a re-run insert copies instead of updating, and duplicates fail rows outright. Clean the SKU column and validate the file structure before uploading, because repairing a corrupted catalog afterwards is manual work.

Share this guideLinkedInXWhatsAppFacebook
All guides