Conversion
Shopify CSV to Google Merchant Center
A Shopify product export is close to a Google feed but not the same file: the headers differ, extra variant rows leave product fields blank, images sit on rows of their own and descriptions are HTML. The mapping below converts it; the sample Google CSV is downloadable; and the last section shows why connecting Shopify directly beats re-uploading a CSV every week.
We connect your store, build the feed and keep it in sync. Updated 2026-10-27.
At a glance
- Shopify exports from Products → Export; an all-products export is emailed, and the CSV uses headers such as Title, URL handle, Description, Vendor, SKU, Price, Compare-at price, Inventory quantity and Product image URL.
- In the export, only a product's first row carries Title, Description, Vendor and Tags; later variant rows skip them, and each image is its own row. A Google feed needs every field on every row.
- Merchant Center fetches a delimited text or XML file from a URL (up to 4 GB) on a schedule; a Google Sheet holding the converted rows is the easiest URL for a one-time CSV.
- Textfinity reads Shopify natively, so the CSV step disappears: products and variants arrive complete and the mapping below is applied on every sync.
Shopify CSV columns to Google Merchant Center attributes
| Shopify CSV column | Google attribute | Conversion rule |
|---|---|---|
| SKU | id | Rename; max 50 chars; fall back to the handle plus option values when SKU matches regexp ^\s*$ |
| Title + Option1 value (+ Option2, Option3) | title | Combine with Vendor; max 150 chars |
| Description | description | Remove from regexp <[^>]+> to strip HTML; max 5,000 chars |
| URL handle | link | Add prefix https://store.example/products/ |
| Product image URL (position 1) or Variant image URL | image_link | Conditional rule: if Variant image URL matches regexp ^\s*$, rename Product image URL; else rename Variant image URL |
| Inventory quantity + Continue selling when out of stock | availability | Conditional rules: in_stock when continue selling is on; else out_of_stock when Inventory quantity matches regexp ^(0|-); else in_stock |
| Price | price | Add suffix " USD" (becomes sale_price when Compare-at is set) |
| Compare-at price | price | When present, this is Google's price and Price becomes sale_price |
| Vendor | brand | Rename; max 70 chars |
| Barcodes | gtin | Rename; leave empty when empty |
| Google Shopping / Google Product Category | google_product_category | Rename; or replace from google sheet on Type, conditioned on is in google sheet list |
| Type | product_type | Rename |
| URL handle (shared by variants) | item_group_id | Rename so Google groups variants |
| Status | (filter) | Keep only active |
Shopify column names from Shopify's current product CSV help page (older exports use Handle, Body (HTML), Variant SKU, Variant Price and Image Src for the same fields); Google attributes and limits from the product data specification; checked 2026-10-27.
Three Shopify CSV quirks that break a Google feed
Blank variant rows. Shopify's format puts all product fields on the first row of a product; additional variant rows carry the URL handle and variant details and skip Title, Description, Vendor and Tags. Converted as-is, every second-and-later variant reaches Google with an empty title and is disapproved. The fix in a spreadsheet is a fill-down on those columns grouped by handle; the fix in Textfinity is to connect Shopify directly, where every variant arrives with its product's fields.
Image-only rows. Each product image gets its own row with the handle and the image URL, and a product can have up to 250. Those rows are not products and must be dropped (filter: SKU is not blank) or folded into additional_image_link.
HTML in Description and a slug instead of a link. The Description column is HTML, and URL handle is a slug. One remove from regexp rule and one add prefix rule turn them into Google's plain-text description and absolute link.
The Google CSV that comes out
A Google-ready file is one row per sellable variant with Google's attribute names in the header. The snippet shows the Shopify side of one product with two variants; the download holds the converted rows. Merchant Center reads the converted file as a delimited text data source, or you keep it in a Google Sheet that Merchant Center or Textfinity fetches.
shopify-export.csv (two variants, second row partial)
URL handle,Title,Description,Vendor,Option1 name,Option1 value,SKU,Price,Compare-at price,Inventory quantity,Product image URL
linen-shirt,Linen Shirt,"<p>Relaxed fit linen shirt.</p>",Marlow,Size,M,MRL-LS-SAND-M,79.00,,12,https://cdn.example/linen-shirt-sand.jpg
linen-shirt,,,,Size,L,MRL-LS-SAND-L,79.00,,0,Skip the CSV: connect Shopify and let the mapping run on every sync
A converted CSV is correct for a day. Prices change, stock moves, and Shopify's all-products export arrives by email, so the loop is export, convert, upload, repeat. Textfinity connects to Shopify natively, pulls products, variants, metafields, markets and locales on the shop's sync schedule, applies the same mapping above and publishes a feed on a stable URL. Dirty feeds rebuild within about five minutes of an edit.
Merchant Center then fetches that URL on a daily schedule once it is added as a product source; we register it with you. The CSV route still has a place: a backup, a store you are migrating, or a catalog you want to profile before you connect anything. For that, paste the export into a Google Sheet and we add the Sheet as the source.
Examples
Worked examples, by situation
The same product in Shopify's export and in Google's format, for three stores.
Second variant row completed and grouped
Before
linen-shirt,,,,Size,L,MRL-LS-SAND-L,79.00,,0,
After
id,item_group_id,title,description,link,availability,price,brand MRL-LS-SAND-L,linen-shirt,"Marlow Linen Shirt, Sand, L",Relaxed fit linen shirt.,https://store.example/products/linen-shirt,out_of_stock,79.00 USD,Marlow
How we set it up
We connect Shopify directly so the L variant arrives with the product's title, description and vendor, then map title as a combine of Vendor, Title and Option1 value with ", ", item_group_id as a rename from URL handle, availability with conditional rules on Inventory quantity, and link with add prefix.
Compare-at price becomes price, price becomes sale_price
Before
SKU: CND-FIG-220 Price: 22.00 Compare-at price: 28.00 Barcodes: (empty)
After
id,price,sale_price,gtin,brand,mpn CND-FIG-220,28.00 USD,22.00 USD,,Wick & Co,CND-FIG-220
How we set it up
We map price with a conditional rule: if Compare-at price matches regexp ^\s*$, add suffix " USD" to Price, else add suffix " USD" to Compare-at price. sale_price: if Compare-at price matches regexp ^\s*$, leave empty, else add suffix " USD" to Price (column names with spaces cannot be read inside an advanced expression, so conditional rules do this). gtin is left empty and mpn is a rename from SKU, so Google has brand plus mpn.
Two markets from one export
Before
Price: 54.00 Price / International: 72.00 (CA market column) Included / CA: true
After
US feed: price = 54.00 USD CA feed: price = 72.00 CAD, link = https://store.example/en-ca/products/<handle>
How we set it up
We build two feeds from one source. CA feed: a filter "Included / CA is equal to true", price as add suffix " CAD" on Price / International, and link with add prefix https://store.example/en-ca/products/. The US feed uses Price with " USD".
Copy this plan
Plan: Shopify export to a Merchant Center data source
Steps 1 and 2 are the CSV route; if you connect Shopify directly, start at step 3.
01
Export from Shopify
Products → Export → all products → plain CSV. The file is emailed for all-products exports. Open it in a spreadsheet, fill the blank Title, Description, Vendor and Tags cells down within each handle, and delete image-only rows (no SKU). This happens in Shopify and your spreadsheet.
02
Put the rows in a Google Sheet
Textfinity reads Google Sheets as a source and re-reads them on every sync, so the Sheet is your feed URL until you connect Shopify.
What we set up: We add the Google Sheet as the source in Textfinity.03
Or connect Shopify directly
Give the feed tool access to the store; products and variants arrive complete, with metafields, markets and locales, and the feed hygiene profile shows what needs a rule.
What we set up: We connect your Shopify store to Textfinity natively.04
Create the Google Shopping feed and map
The template pre-fills Google's attribute names. Map from the table: most are renames, five need a rule.
What we set up: We build the feed from the Google Shopping template and map title as a combine, description with remove from regexp, link with add prefix, price with add suffix and availability with conditional rules.05
Filter inactive and image rows
Keep active products with a SKU and an image.
What we set up: We add filter rules: Status is equal to active, SKU is not blank, Product image URL is not blank.06
Register the feed in Merchant Center
Add the feed URL as a product source in Merchant Center's data sources and schedule a daily fetch. That form is in Google's interface.
What we set up: We register the URL with you: you give us access to Merchant Center, or we walk you through it.
Customization tips
Make it yours
Use the CSV to profile, then connect the store
The export is a quick way to run feed hygiene on a catalog before touching Shopify: completeness per column, titles over 150 characters, barcodes present. Once you see the shape, connect Shopify so the fixes apply to live data.
Map item_group_id from the handle, not the title
Titles get edited; handles rarely do. A stable item_group_id keeps Google's variant grouping intact across edits. If you rename a handle, expect the group to reset.
Send mpn when barcodes are empty
Google accepts brand plus mpn for most new products without a GTIN. Map SKU to mpn rather than inventing a GTIN; a wrong GTIN disapproves the item, an empty one usually does not.
One feed per Shopify market
Price / International and Included / <Market> columns exist per market. A feed per market with its own currency suffix, link prefix and inclusion filter maps cleanly to a Merchant Center target country.
Downloads
Take the files
FAQ
Questions about shopify csv to google merchant center
Can I upload a Shopify CSV straight to Google Merchant Center?
Not as exported. The headers are Shopify's, later variant rows skip Title, Description, Vendor and Tags, and images are separate rows. After renaming the headers to Google's attributes, filling the blanks and dropping image rows, the file is a valid delimited text data source; a Google Sheet is the easiest URL for it.
Is a Shopify CSV better than the Google & YouTube channel?
The channel syncs automatically and is the right default. A converted file gives you control over titles, custom labels and filters, but goes stale as soon as prices change. A feed tool that reads Shopify directly gives the control without the manual loop; with Textfinity we set that up for you.
Why are my variants missing titles after converting the CSV?
Shopify's CSV carries Title, Description, Vendor and Tags only on a product's first row; later variant rows leave them blank. Fill those cells down within each handle in a spreadsheet, or connect Shopify directly so every variant arrives complete.
What do I do with the image rows in the export?
Rows that have a handle and a Product image URL but no SKU are image rows, not products. Drop them with a filter (SKU is not blank), or fold the extra URLs into additional_image_link; Google allows several additional images per item.
Set up for you
Have us replace the Shopify export with a live feed.
Send us the export or give us access to the store. We map the fourteen columns above in Textfinity and register the feed with you in Merchant Center; the software keeps it in step with Shopify on every sync.
Tell us your store and channels. We reply within 24 hours.