CFCSV Forge

WooCommerce to Shopify: converting a product CSV export

A WooCommerce export and a Shopify import describe the same catalogue with incompatible row models. These are the four differences that actually break the import, and what each one has to become.

Open the tool with this presetField names verified against a published export spec.

Where the file comes from

In WordPress admin go to Products → All Products → Export, leave the column selection at “all”, and export. You get a CSV whose header includes Type, SKU, Name, Parent, Regular price, Stock, Images, Categories, and numbered attribute pairs like Attribute 1 name / Attribute 1 value(s). The field names are documented in WooCommerce’s product CSV importer/exporter reference, and Shopify’s own migrating-from-WooCommerce guide names Regular price, Stock and Weight (lbs) explicitly.

Pitfall 1: the variable parent row is not a variant

WooCommerce exports a variable product as one row of Type: variable followed by one row of Type: variation per purchasable combination. The parent row holds the title, description and image gallery, but its attribute cells hold the list of allowed values — Small, Medium, Large — not one value.

Copy that parent row through as a variant and Shopify sees a variant whose option value is either blank or the literal string “Small, Medium, Large”. If another variant is also blank you get Validation failed: options are not unique; if not, you get a phantom variant customers can buy. The parent row must contribute product-level fields only, and the variation rows must become the variant rows. This tool detects that shape — multiple rows grouped by Parent, where the first row’s attribute cells are lists rather than single values — and splits the roles automatically.

Pitfall 2: Parent is empty on the parent

The Parent column is a back-reference: it is filled on variation rows and empty on the parent itself. Grouping naively by Parent therefore throws every parent of every product into one group keyed by the empty string, collapsing your whole catalogue into a single product.

The grouping key has to be “Parent if present, otherwise this row’s own SKU”. That is what the auto-detect does when it sees a parent-reference column, which is why leaving grouping on auto-detect is correct for WooCommerce files and picking Parent manually is not.

Pitfall 3: the Images cell is a gallery

WooCommerce packs the whole gallery into one cell, comma- or pipe-separated, featured image first. Shopify needs the first URL in the product’s first row and one additional row per remaining image, each carrying only the handle, Product image URL and an incrementing Image position.

Select the split image list formula on Product image URL and those extra rows are generated. Three images across four variants becomes four variant rows plus two image rows — six rows for one product. Note that variation-specific images belong in Variant image URL on that variant’s own row, which is a different column.

Pitfall 4: pounds, and HTML in the description

WooCommerce exports weight in your store’s unit, commonly Weight (lbs). Shopify stores one integer in grams. Set the source weight unit to lb and 0.75 lb becomes 340 grams, rounded, with Weight unit for display set separately. Leaving it on grams imports a 0.75 lb shirt as under a gram, and your shipping rates quietly break.

Descriptions arrive as HTML (<p>, <ul>, often shortcodes and block comments). Shopify accepts HTML in Description, so this mostly works — but WooCommerce-specific shortcodes like [product_table] render as literal text on your Shopify product page. Search your export for [ before importing.

What the preset maps

Name → Title, SKU → SKU, Regular price → Price, Stock → Inventory quantity, Weight (lbs) → Weight value (grams) with lb conversion, Images → Product image URL with splitting, Categories → Type, Tags → Tags, and Attribute 1/2 name and value(s) → the Option1/Option2 pairs. Grouping is left on auto-detect so the Parent-plus-SKU rule applies.

Two WooCommerce concepts have no Shopify CSV equivalent and are deliberately dropped: Shipping class (Shopify models this with shipping profiles, set in the admin, not per-product in the CSV) and Tax status/Tax class (Shopify has a boolean Charge tax plus an optional Tax code; a WooCommerce tax class name will not match an Avalara code). Set Charge tax as a constant instead.

Before you upload to Shopify

  • Import into a development store or a draft-status batch first. Set the default status to draft in the tool and nothing goes live by accident.
  • Shopify caps a product CSV at 15 MB. Bigger catalogues are split into numbered parts, and a product is never split across two files.
  • Overwriting existing products by handle is destructive: a blank cell can erase data that is currently there. Export your live products first if you are updating rather than creating.

Full column contract: the Shopify product CSV format, column by column. CSV Forge is not affiliated with Shopify Inc.