DEV Community

Eli
Eli

Posted on • Originally published at clawmama.run

Google kept rejecting a bookstore's print listings — because the ebook was still buyable on the same URL

I stumbled onto this one in a Shopify Community thread that had 13 answers and no accepted one. A book publisher sells every title in three formats — print, ebook, audiobook. They did what every feed management app tells you to do: exclude every digital edition from the Google Merchant Center data source. And Google's automated review kept rejecting their print book listings anyway.

I've seen "just filter the feed" handed out as the complete answer to this problem for years, so I dug into why it wasn't working. The reason is structural, and it's documented — just not in one place. Here's the whole picture.

The structural fact that explains everything

One respondent in the thread (dropfeed) actually audited the merchant's catalog: 423 of the store's 480 products carry a single Format option with Audiobook, Ebook, Paperback and Hardcover as variants of one product. All four formats share one URL and one item group.

Hold that fact next to three documented ones:

  1. Google's Shopping policies don't support ebooks. The "Unsupported Shopping content" policy lists "eBooks and digital books (not including audiobooks)" — PDFs, ePub, MOBI — as content that cannot be promoted.
  2. Google evaluates the landing page, not just the feed. The landing page requirements: when your page contains multiple products "such as variants", the product in your product data must be the primary focus and the price must match. The link attribute doc: one link per product or product variant. And Google's structured data docs show variants are addressed by preselecting via URL parameters (?size=small&color=green).
  3. On the submitted URL, the ebook is still buyable. Ebook and audiobook are variants of the same Shopify product, so the print URL renders one Add to Cart form whose Format picker lets anyone select — and purchase — a digital edition.

The thread converged on a precise dividing line (field report, but consistent with the policy pages):

  • Allowed: mentioning "also available as ebook and audiobook" in the product copy. Text is not an offer.
  • Rejected: ebook/audiobook as selectable, purchasable variants in the Add to Cart form on the submitted URL.

That's why filtering the feed changed nothing: the merchant cleaned the data Google reads, not the page Google visits. Preselecting the paperback variant doesn't fix it either — the digital options are still one click away in the same form, still purchasable, same URL.

A quieter amplifier: if your product page emits JSON-LD offers for the digital variants (many themes and apps do), crawlers read the ebook as an offer even where a human sees only a dropdown. Google's ProductGroup pattern (hasVariant, variesBy, productGroupID) is correct markup for genuine multi-format pages — and a liability when some variants are unsupported content.

Minimal reproduction (no Google required)

The failure is structural and visible in Liquid on any dev store:

  1. Create one product, dune, with option Format: Paperback ($18, requires shipping), Ebook ($9, digital), Audiobook ($15, digital).
  2. Exclude the digital variants from your Google feed by whatever method you like.
  3. Open the product URL with the paperback preselected: /products/dune?variant=<paperback_variant_id>.
  4. View source. The Add to Cart form posts a variant id, and the Format selector still contains all three options. Any crawler sees three purchasable offers — two of them digital — on the submitted URL.

Feed-side exclusion verified; landing-side exposure intact.

Route A — Split the formats into separate products (the structural fix)

Print, ebook, and audiobook become separate Shopify products. Publish only the print products to Google surfaces; keep the digital products on the storefront, linked from the print page as text ("Also available as ebook / audiobook"). The submitted print URL offers only physical formats — exactly what passes review.

The merchant's objection is real: this multiplies the catalog 3-4x. Mitigations exist but don't eliminate the cost — bulk editors, metafield-driven cross-links, and for programmatic control the Admin GraphQL API (publicationCreate publishes a product to a channel; channel availability is product-level, and tags/metafields alone do not control sync).

Route B — Proxy page: a physical-only offer page per title (the theme fix)

Keep the variant structure. Create an alternate page template that renders only the physical variants of a given product, and submit those proxy URLs to Google. Shopify theme architecture supports alternate templates, and Liquid gives full markup control. Pull the product with all_products['your-handle'] and filter variants by requires_shipping — true for physical goods, false for digital ones:

{%- comment -%} templates/page.print-proxy.liquid {%- endcomment -%}
{%- assign book = all_products['dune'] -%}

<h1>{{ book.title }} — Print edition</h1>

<form method="post" action="/cart/add">
  <label for="fmt">Format</label>
  <select id="fmt" name="id">
    {%- for variant in book.variants -%}
      {%- if variant.requires_shipping -%}
        <option value="{{ variant.id }}">
          {{ variant.title }}{{ variant.price | money }}
        </option>
      {%- endif -%}
    {%- endfor -%}
  </select>
  <button type="submit">Add to cart</button>
</form>
Enter fullscreen mode Exit fullscreen mode

Mapped to the requirements:

  • The proxy URL's only purchasable options are physical. The offer on the page matches the submitted offer.
  • One product, one clean URL to submit as the link — Google wants exactly one link per product or variant.
  • Digital editions stay on sale at the canonical product URL, linked as text — copy, not an offer.

Two documented constraints:

  • all_products resolves at most 20 unique handles per page. One proxy page per title is fine; proxying a whole catalog from one page is not — use collections or one page per handle.
  • Keep the proxy page's JSON-LD honest: emit structured data only for the physical offers on the page; don't list digital variants as offers on the proxy URL. When you submit variant URLs elsewhere, preselect via URL parameters so price/availability match.

More template work than Route A, but the catalog survives.

Route C — GMC attribute rules with excluded_destination (the feed-hygiene fix)

Worth doing regardless of the structural route. In Merchant Center, "feed rules" are now called attribute rules (Google renamed them). Add a rule on your data source that sets excluded_destination when the title matches digital markers (e.g. "title contains ebook"), excluding from Shopping ads, free listings, display, etc. The attribute is documented precisely for preventing a product from appearing in chosen destinations.

What it does and doesn't:

  • Does: guarantee no digital SKU is ever submitted, even if your sync app misbehaves or a new digital product is added without tags.
  • Does not: change what a crawler finds on a shared-format product URL. Necessary hygiene, not a cure.

On sync: the Google & YouTube app syncs Shopify product data to Merchant Center automatically or manually — attribute rules sit after the data arrives, which is why they catch what channel-side visibility settings miss.

Checklist

  • Inventory: which products mix physical + digital formats as variants of one product? (The merchant's audit: 423 of 480.)
  • Classify every digital format against Google's Unsupported Shopping content list — ebooks explicitly listed; audiobooks explicitly not in that entry, but treat any instant-download good as suspect until verified.
  • Confirm the failure mode first: does the submitted URL offer digital formats for purchase? If yes, feed filtering alone can't clear the rejection.
  • Pick the structural route: split products (A) or proxy pages with requires_shipping-filtered forms (B). Text mentions can stay; purchasable selectors cannot.
  • Add GMC attribute rules setting excluded_destination on digital markers as a safety net regardless.
  • Audit JSON-LD on submitted URLs: emit only offers that are purchasable and supported; keep digital variants out of the proxy page's markup.
  • Submit one link per product/variant; preselect variant URLs via parameters so price and availability match.
  • After fixing, request a review on the affected items and watch for re-disapproval.

The community thread content (catalog audit, the "purchasable variant" diagnosis, the proxy-page suggestion, the attribute-rules recipe) is a field report from Shopify Community topic 658986; every load-bearing technical claim above is verified against Google and Shopify documentation (Unsupported Shopping content policy, landing page requirements, link/excluded_destination attributes, attribute rules, product-variant structured data, Liquid all_products/variant, theme templates, Admin GraphQL publicationCreate — latest stable 2026-07).

Originally published at https://clawmama.run/blog/shopify-gmc-format-variant-rejection/

Top comments (0)