Skip to content
feedlab Request early access

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.

Example transformations for Shopify handle to link
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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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

Attributes involved

Related concepts

Primary sources

Channel specifications change. These are the official documents this page is based on.

Last reviewed View as markdown