Shopify field mapping
Shopify handle to link
product.handle
link
The product link is built from the store domain and the Shopify handle, with a variant parameter appended so each feed row lands on its own variant. The details that matter are which domain you use, whether the variant is preselected, and what happens when a handle changes.
The Shopify side
- API field
- product.handle
- Called
- URL handle
- Found at
- Product → Search engine listing → Edit → URL handle
- Feeds
- link
Before and after
Real values on the left as Shopify stores them, on the right as a channel needs them.
| In Shopify | In the feed | Note |
|---|---|---|
| handle "oxford-shirt", variant 101 | https://example.com/products/oxford-shirt?variant=101 | The variant parameter is what makes each row land on its own variant. |
| handle "oxford-shirt" (no variant) | https://example.com/products/oxford-shirt | Valid, but every variant row points at the default selection. |
| myshopify domain | https://example.com/products/oxford-shirt?variant=101 | Built from the customer-facing domain rather than the internal one, which redirects. |
| German market | https://example.de/products/oxford-shirt?variant=101 | Market-specific domain, so the shopper arrives in the right currency. |
| handle with tracking | https://example.com/products/oxford-shirt?variant=101 | Tracking parameters left out of the feed and configured at channel level instead. |
The transformation, step by step
-
Use the canonical customer-facing domain
Build the URL from the domain shoppers actually use, not the myshopify.com address. The internal domain usually redirects, and channels compare the feed URL against the page they land on, so a redirect chain is an avoidable risk on every row.
-
Append the variant parameter
Add ?variant= with the variant id so the correct size and colour is selected on arrival. Without it, every variant row points at the same page showing whichever variant is default, and a shopper who clicked a large black shirt sees a small white one.
-
Keep the URL stable and clean
No session parameters, no tracking parameters that vary per generation. A URL that changes between feed runs looks like a different landing page to the channel, and tracking belongs in a channel-level setting rather than baked into the feed.
-
Handle localised domains per market
A store selling into several markets serves different domains or path prefixes per market, and the feed for each market needs its own. Sending one domain to every market means shoppers land in the wrong currency or get redirected.
-
Watch for handle changes
Changing a product title in Shopify can change the handle, which changes the URL. The old URL usually redirects, but a feed carrying the old value is one redirect away from a mismatch, so the handle should be read fresh on each generation rather than cached.
What goes wrong
Without ?variant= every row is the same page
A variant-level feed with product-level URLs sends every size and colour to one page showing the default variant. Nothing is reported, the price on the page can differ from the feed, and the shopper has to reselect what they already chose.
The myshopify domain is a redirect
Feeds built from the internal domain work, then add a redirect to every crawl. When the channel is comparing feed values against landing-page content, an unnecessary redirect is an unnecessary way for that comparison to fail.
Unpublished products still have handles
A draft or unpublished product has a handle and therefore a constructible URL, which returns a 404 to the channel. The URL being buildable is not evidence that the page exists, so publication state has to be checked separately.
Redirects hide a stale feed
Shopify creates a redirect when a handle changes, so an old URL keeps working and nothing appears broken. Meanwhile the feed is carrying URLs that no longer match the canonical page, which shows up as a landing-page mismatch rather than a broken link.
How feedlab maps it
feedlab builds the link from the market's canonical domain, the current handle read at generation time, and the variant id, and excludes products that are not published to the sales channel so no row points at a 404. Tracking parameters stay out of the URL.
Frequently asked questions
Should the feed link include the variant parameter?
Yes, on a variant-level feed. Without ?variant= every row lands on the same page with the default variant selected, so the shopper sees a different item from the one they clicked.
Which domain should a Shopify feed use?
The customer-facing one. The myshopify.com address redirects, and channels compare feed values against the page they reach, so an unnecessary redirect on every row is an unnecessary risk.
What happens to the feed when a product handle changes?
Shopify adds a redirect, so the old URL still works and nothing looks broken. The feed is then pointing at a non-canonical URL, which is why the handle should be read fresh each time rather than stored.
Can I add UTM parameters to feed links?
You can, but the URL must be stable between generations. Channel-level tracking settings are the better place for it, and they keep the feed value canonical.
Errors this mapping causes
- Mismatched value: price The price mismatch error means the price in the feed does not agree with the price the channel found when it crawled the landing page. On Shopify the three usual culprits are a feed that has not regenerated since a price change, a link pointing at the wrong market's storefront, and a tax convention difference between the feed and the displayed price.
- Mismatched value: availability The availability mismatch error means the feed says an item is purchasable but the crawled landing page suggests otherwise, or the reverse. On Shopify it is usually a stale feed after a sell-out, or an availability value derived from inventory quantity alone without accounting for variants that do not track inventory or that allow overselling.
Attributes involved
- link The link attribute is the URL a shopper is sent to after clicking a listing, and the page the channel crawls to verify that the feed is telling the truth about price and availability. On a multi-market Shopify store it must point at the market-specific storefront URL, not the primary domain.
- id The id attribute is the unique, permanent identifier a sales channel uses to recognise one item across every feed update. In a Shopify feed it must identify a single variant rather than a product, and once a channel has seen an id it should never be reused for a different item.
Related concepts
Primary sources
Channel specifications change. These are the official documents this page is based on.