If you sell into Canada and you're running one Google Shopping feed in English, you're leaving the Quebec half of the market on the table and, depending on how your storefront is built, you may already be collecting disapprovals you haven't looked at. The fix for a google shopping feed for Canada in French is structural, not cosmetic: two feeds, one per language, each pointing at a landing page that is actually in that language in the HTML the crawler receives. Translate the feed without translating the destination and Google will disapprove the offer. Translate the destination with a JavaScript overlay and it will disapprove it too, because the crawler sees English.
Everything else in this post is downstream of that one rule.
Two feeds, one catalogue: how the French and English split works in Merchant Center
Merchant Center treats country and language as a pair. A feed is registered for Canada in English, or Canada in French. The same product can appear in both, and should — it's the same offer, submitted twice, with a different title, description, link and sometimes a different image if your creative carries text.
So setting up French and English feeds in Google Merchant Center means two primary feeds with the same id values in each. Same IDs matter. If your French feed generates its own SKU-prefixed IDs, Google can't tie the two offers together and your reporting splits in ways that make campaign decisions harder than they need to be.
Shopify's own Google sales channel will publish your primary language cleanly and that's usually where merchants stop. For the second language you need either a feed app that reads your Shopify Markets translations, or a supplemental feed keyed on id that overwrites title, description and link for the French offers. The supplemental route is cheap and it works, but it only overwrites what you give it, so a product added last week with no French translation inherits the English title and sits in the French feed misrepresenting itself.
Do the arithmetic before you build. A 2,400-SKU catalogue submitted in two languages is 4,800 offers. If your Quebec-facing translations cover 1,900 products, 500 French offers are going to ship with English titles against a French landing page, or the reverse. Neither passes. Either finish the translation for the subset you actually advertise, or restrict the French feed to that subset with a filter and leave the rest out.
Shopify Markets language URLs are where this usually breaks
Shopify Markets gives you /fr/ subfolder URLs or a language-specific domain, and it emits hreflang between them. That part is solid. Three things go wrong around it.
- Canonical tags pointing home. If a theme customisation or an app sets the canonical of /fr/products/handle back to the English URL, the French page stops being an independent destination. Shopify's native translation doesn't do this. Third-party translation apps sometimes do.
- Automatic redirects by browser language. Geolocation and language redirects are a convenience for shoppers and a trap for crawlers. If a request with an English-ish header gets bounced from /fr/ to the root, Google follows the redirect, lands on English, and compares that against your French feed. Disapproval. Serve the URL that was requested, and use a dismissible banner to suggest the other language instead.
- Client-side translation. Apps that swap text in the browser leave the server response in English. Merchant Center's language check reads the response. We've had merchants show us a perfectly French product page on screen while the feed's French offers were all disapproved, which is a confusing half-hour until you view source.
Put the language URL into the feed's link attribute directly. Don't rely on a parameter like ?locale=fr unless you've confirmed it renders server-side and returns 200 without redirecting.
What a landing page language mismatch disapproval actually looks like
In the Merchant Center diagnostics it shows up as an item-level issue about the landing page not matching the declared language of the feed, and it is usually all-or-nothing: either three French offers are flagged because someone forgot to translate three descriptions, or the entire French feed is dark because of a redirect rule. The second case is more common and easier to fix.
Check it the way Google does. Fetch the French product URL with curl, no cookies, and look for a French <title> and a <html lang="fr"> in the raw response. If you get a 302 or an English title, you've found it. Thirty seconds, no tooling.
The subtler version: a French title and description with English size labels, English care instructions pulled from a metafield, and an English size chart image. Google rarely disapproves for that. Quebec shoppers bounce for it, which costs more.
Shipping attributes by province, and the Canada Post problem
Canada is one of the few markets where flat-rate shipping in Merchant Center is close to a lie. You can set shipping at the account level with regions, or per-item in the feed with the shipping attribute as country:region:service:price. For most catalogues, account-level shipping services built from province groups plus a separate group for the territories and remote postal codes is the right call, and the feed only overrides it for oversize items.
Build at least three groups: the Toronto–Montreal–Vancouver corridor, the rest of the provinces, and Yukon, Northwest Territories, Nunavut and remote postal code ranges in northern BC, the Prairies and Newfoundland. A parcel that ships to a Toronto postal code for $9.95 can cost you $34 to Whitehorse. Submit $9.95 for the whole country and you're buying every northern click on a promise that costs you $24 more to keep.
Free shipping thresholds are the other mismatch generator. If your feed says free over $99 and your Shopify rule applies the threshold after discounts, a $110 item at 15% off is $93.50 and the customer gets charged shipping on a listing that said otherwise. Pick one and make them agree.
Then there's the carrier question. Canada Post disruptions have taught every Canadian merchant to keep a fallback — Purolator, UPS, Intelcom, GoBolt, whoever you've got rated. When you switch, your transit times change and your Merchant Center shipping speeds go stale. Delivery estimates feed into the free-and-fast badge and into shopper expectation. Reviewing them is a ten-minute job that nobody puts on the contingency checklist. Put it on yours.
Price and tax: submit what the page shows
The rule to work from is that the feed price must equal the price a shopper sees on the landing page in that language. For Canadian stores running Shopify's default pre-tax display, that means pre-tax prices in the feed, with GST/HST/PST/QST applied at checkout. Problems start when someone turns on tax-inclusive pricing for one market and not another, or when a Quebec-targeted price adjustment in Shopify Markets changes the displayed figure for /fr/ pages but the French feed still carries the English price.
Check both languages when you audit price mismatches. They diverge quietly.
Sale timing deserves a line of its own because Boxing Day is a genuine second peak in Canada and the sale_price_effective_date attribute is timezone-sensitive. Set your feed timezone to America/Toronto and write the dates against it, or your midnight-ET price drop goes live at 7pm on the 25th. We've seen that one cost a full evening of margin.
GTIN and barcode errors in Shopify feeds
Shopify's barcode field is a free text box, which is why this is the most common error class we find in Canadian feeds.
- Invalid check digit. Someone typed a 12-digit UPC into a 13-digit field or dropped a character. Google validates the check digit and rejects the offer outright.
- Internal store codes. Barcodes starting with 2 are reserved for in-store use. A lot of POS-generated codes land there. They will never validate.
- The same barcode on every variant. Each size and colour needs its own GTIN. Duplicating one across a size run makes Google treat them as the same offer and suppress the rest.
- Private-label products with no GTIN at all. This is fine, and you don't need to buy barcodes. Send identifier_exists: false along with a real brand and a stable mpn. What isn't fine is leaving the field blank with no flag, which gets you a "limited performance" warning and lower impression share.
Make the same decision in both feeds. A product flagged as having no identifier in English and left blank in French will behave differently in each, and you'll spend an afternoon wondering why the French offers underperform.
Excluding out-of-stock products from a Shopify feed
Shopify's Google channel syncs availability automatically, so an item that hits zero inventory is marked out of stock and stops serving. Two things defeat that. One, "continue selling when out of stock" keeps the item reporting as available, which it genuinely is if you're on backorder and genuinely isn't if you forgot the setting was on. Two, pre-orders need availability: preorder with an availability_date, not a quiet exclusion.
Our rule of thumb: if restock is inside two weeks, leave it in the feed marked out of stock so the offer keeps its history. Past that, exclude it with a feed rule or a metafield-driven filter so it isn't dragging your account's item health down for a quarter. Don't delete products to exclude them. You lose the ID and you start over on performance data when it returns.
Performance Max for a bilingual Canadian store
Run two campaigns, one per feed label. Not one campaign with two asset groups.
The reason is budget control. Asset groups inside a single Performance Max campaign don't carry independent budgets, so a French asset group with thinner creative and less conversion history gets starved by the English one and you can't tell whether French underperforms or was simply never funded. Split the feed with the feed_label attribute, point each campaign at its own label, set the campaign language accordingly, and give the French campaign enough daily spend to exit the learning phase on its own. If the French side can't support that budget, run it as a standard Shopping campaign instead and accept the narrower inventory.
Creative matters more than the targeting setting here. Google's language targeting keys off a user's interface and content language signals, and it is loose. What actually keeps your French campaign relevant is French headlines, French descriptions, French text in images, and a landing page that stays French after the click.
Quebec targeting in Google Ads, and the part that isn't a marketing decision
Quebec is roughly a fifth of the country by population and most of the French-first demand sits there, though not all of it — there are substantial francophone markets in New Brunswick and eastern Ontario, and you'll see conversions from both once the feed is clean.
For a merchant with real French creative, the useful split is a Quebec-only campaign with its own budget and a national English campaign, with Quebec excluded from the English one if your French assets are strong, or left in if they're not. Watch the data for a month before deciding. Montreal in particular converts on English listings at a rate that surprises people.
The thing that isn't optional: Quebec's language legislation, Bill 96, pushes French commercial communication aimed at Quebec consumers from a nice-to-have to a compliance question, and that includes the storefront behind the ad, not only the ad text. We're not lawyers and you should get an opinion from someone who is, but plan your build on the assumption that a Quebec-facing storefront needs French that is at least as prominent as the English, and that "we machine-translated the product titles" is a weak position to be in. A proper bilingual catalogue is the same work as a proper French feed, which is convenient. Do them together. Our content and SEO team handles the catalogue side of this when the volume is beyond what a founder can edit by hand.
The order we build these in
Language URLs first, because nothing downstream works without them. Then the English feed, clean, with GTINs sorted and shipping groups built. Then the French feed as a supplemental overwrite on the same IDs, checked with a raw fetch on five product URLs before you ask for review. Campaigns last.
Expect the first French feed submission to throw errors. We get a handful wrong on the first pass too, usually a redirect rule someone added for a Black Friday landing page eight months earlier that nobody remembered.
If you want a second pair of eyes on an existing setup, our free store audit covers feed health alongside the rest, and the Canada page has more on how we work with merchants here.


