Skip to article
Product Recommendations Jul 15, 2026 35 min read

Shopify Product Recommendations Not Working: Diagnose Missing, Empty, or Wrong Results

The fastest way to diagnose Shopify product recommendations is to separate the native candidate response from the storefront that renders it. If Shopify returns the expected product, inspect the theme. If Shopify returns no products, inspect intent, manual configuration, and eligibility. If the request fails, inspect the anchor and request itself.

This distinction prevents a common waste of time: changing Search & Discovery settings while a theme selector is broken, or editing theme code while every expected candidate is being filtered out correctly.

The guide covers native related and complementary recommendations in Search & Discovery, Online Store themes using the Ajax API, and headless storefronts using the Storefront API. A third-party recommendation app can resemble these surfaces, but its candidate and tracking rules must be verified against that app.

Evidence boundary

Shopify facts below are scoped to official Search & Discovery, theme, Ajax API, Storefront API, standard-metafield, and analytics documentation checked July 28, 2026. This article does not claim that a third-party app follows the same path. No live store was available for this rewrite, so runtime claims are framed as reader-run tests with observable outcomes.

Chapter 1 · Fast native proof

Ask Shopify for the candidates before changing the theme

For an Online Store theme, the native JSON endpoint is the cleanest dividing line. Replace YOUR_PRODUCT_ID with the numeric anchor product ID from its Shopify admin URL, open the request on the storefront domain, and preserve any locale prefix used by the storefront.

Reader-run request

/recommendations/products.json?product_id=YOUR_PRODUCT_ID&limit=4&intent=related

Change related to complementary to test the second intent. Shopify accepts a limit from 1 to 10.

200 · products

Native source works

Compare returned product IDs and URLs with the visible cards.

200 · empty

Request worked

Inspect intent, manual relationships, eligibility, and cart state.

404

Anchor rejected

The product ID does not exist or the anchor is not published to Online Store.

422

Request rejected

The product ID is missing or the intent is not related or complementary.

This visual separates four response states that look identical when a theme hides an empty or failed module. It does not test a headless storefront or a third-party recommendation app.

A successful empty response is useful evidence. It proves that the route, anchor, and intent were accepted, but no candidate survived for that request. A successful response containing products shifts the investigation downstream to section rendering, card projection, or tracking.

Do not use the section’s initial HTML as the same proof. Shopify documents that the recommendations Liquid object is not populated on the initial render. Theme JavaScript retrieves the populated section asynchronously, so an initially empty placeholder can be expected.

Chapter 2 · Symptom map

Use the visible symptom to choose the first checkpoint

Do not begin by adding more manual recommendations. First describe exactly what the shopper sees and where. The symptom narrows the possible owner before you touch configuration.

Use a clean browser session when cart state matters. Shopify excludes products that are already in the visitor’s cart, so the same anchor can produce a different candidate set after an add.

Visible symptomFirst checkpointDo not start with
The section is absent on every productTheme support, product template, section or block placement, and enabled stateManual product selection or automatic recommendation quality
The section appears on some products onlyTemplate assignment, anchor publication, empty response handling, and anchor identifierA site-wide theme rewrite
Related products show, complementary products do notIntent, manual complementary selection, candidate inventory, and theme block supportAssuming both intents use the same rules
The module is present but emptyAnchor request, candidate response, eligibility exclusions, and empty-state rendererChanging the heading or card design
Products appear but are not usefulRecommendation intent, candidate source, catalog evidence, and manual or automatic modeTreating a relevance problem as a visibility problem
The right product has the wrong price, image, or URLAPI response, variant selection, card projection, cache, and clicked destinationReplacing the recommendation source
The storefront looks correct but reports are emptyTracking parameters, visible impression, click path, event scope, consent, and report rangeTuning candidates based on missing analytics

Chapter 3 · The native path

Trace the anchor and candidate as separate identities

The anchor is the product the recommendation request is about. The candidate is a product that may be returned. An invalid anchor can prevent the request from succeeding. An ineligible candidate can produce a valid but empty result.

Preserve both identities through the test. “The boot page” and “the spray” are not enough when templates, duplicated products, variants, combined listings, or market-specific offers exist. Record the product IDs and the exact storefront context.

Native recommendation trace

Template

Section or block

Anchor

Product ID + intent

Eligibility

Candidate gates

Response

Products or HTML

Storefront

Card + tracking

Trace key: anchor ID · candidate ID · intent · template · locale · market · cart state · response · rendered URL

The same heading can conceal different systems. A “You may also like” row in an Online Store theme can use the Ajax endpoint, while a headless storefront can query Storefront API and a third-party app can use neither. Identify the surface before applying a fix.

SurfaceIts jobEvidence it providesWhat it does not prove
Search & Discovery adminStores manual relationships and related-product display modeThe anchor has the intended related or complementary selectionsThat the active theme requests or renders them
Online Store themeRequests recommendation HTML or JSON and renders the cardsNetwork response and the final DOM agree on product identityThat a headless or app-owned module uses the same path
Ajax Product Recommendations APIReturns native candidates or rendered section HTMLStatus, intent, returned IDs, URLs, and section responseThat theme JavaScript inserts the response correctly
Storefront APIReturns recommendation products to a headless storefrontThe productRecommendations query returns the expected intent and productsThat an Online Store theme uses Storefront API
Third-party recommendation appDefines its own candidates, rendering, and tracking contractThe app request, response, and implementation documentationAnything about Shopify’s native recommendation output

Chapter 4 · Eligibility contract

Related and complementary products do not share every rule

Shopify evaluates product state before a recommendation appears. Check the candidate that you expected, not only the products that survived into the module.

The inventory distinction matters. Shopify currently allows a related product with zero inventory to display when “continue selling when out of stock” is enabled. Complementary products require inventory above zero. A product can therefore appear for one intent and disappear for the other without a theme bug. These and the other candidate gates are listed in Shopify’s recommendation requirements.

Candidate ruleRelatedComplementaryStorefront proof
Active statusRequiredRequiredCandidate product status in Shopify admin
Online Store publicationRequiredRequiredCandidate is published to the Online Store sales channel
Price above zeroRequiredRequiredCurrent product or relevant variant offer
InventoryCan display at zero when continue selling is enabledInventory must be above zeroInventory plus continue-selling policy for the relevant item
Unlisted or gift cardExcludedExcludedProduct type and unlisted state
Already in visitor cartExcludedExcludedRepeat the test in a clean session and after adding the candidate

Cart state is part of the test context

If the candidate disappears after it is added to cart, that can be expected native behavior. Test once in a clean session and once after adding the candidate. Record both outcomes instead of calling the second response inconsistent.

Chapter 5 · Candidate source

Find the system that actually produced the visible row

A Shopify storefront can contain a native related-products section, a complementary-products block, manual Search & Discovery relationships, Shopify’s automatic related products, an Ajax or section request, and a third-party app at the same time.

Do not infer the source from the heading. Theme copy such as “You may also like” can sit above several different systems. Inspect the template code, request, or app block and record the source explicitly.

Candidate sourceWhere it is controlledExpected behaviorInspect first
Manual related productsSearch & Discovery or the related-products standard metafieldUp to 10 selected products in “only manual” or “ahead” modeSelection, display mode, order, request limit, eligibility, and ownership
Manual complementary productsSearch & Discovery or the complementary-products standard metafieldUp to 10 selected add-ons that pass complementary eligibilitySelection, stock above zero, active state, publication, price, and cart state
Automatic related productsShopify-generated related recommendationsOutput can use purchase history, product descriptions, or related collectionsNative order history, English-storefront condition for descriptions, collections, and combined-listing settings
Ajax JSON or section responseOnline Store theme or custom theme JavaScriptRelated or complementary output for the supplied product ID and locale-aware routeRequest parameters, status, payload or HTML, section ID, and tracking URL
Storefront APIHeadless storefrontUp to 10 products for RELATED or COMPLEMENTARY intentProduct ID or handle, intent, returned product fields, card mapping, and analytics

Related and complementary are not two labels for the same candidate set. Shopify generates related recommendations automatically and lets a merchant add manual related products. Complementary recommendations require manual configuration in Search & Discovery. A request using the wrong intent can therefore return a technically valid but empty set.

Manual relationships are stored in Shopify-reserved standard metafields. This matters when another app, Flow workflow, bulk editor, or migration changes the same values. The Search & Discovery screen is not a separate source of truth.

ControlReserved namespace and keyTypeEffect on recommendations
Related productsshopify--discovery--product_recommendation.related_productslist.product_referenceStores the manually selected related products. It does not contain Shopify-generated products.
Related products displayshopify--discovery--product_recommendation.related_products_displaysingle_line_text_field“only manual” returns the selected set only. “ahead” puts selected products before generated products.
Complementary productsshopify--discovery--product_recommendation.complementary_productslist.product_referenceStores manually selected add-ons. Shopify does not auto-generate this intent.

Only manual

Exact curated source

Only selected related products are considered. If every selected product becomes ineligible, the result can be empty.

The eligibility filter still runs

A configured relationship is not a promise that the candidate will display. Product state, stock rules, cart state, and the request limit can reduce the visible set.

Ahead

Manual first, generated after

Selected related products lead the set. Generated related products can provide coverage after them.

For generated related products, Shopify documents three inputs: products bought together, similar product descriptions, and related collections. Purchase history requires prior sales. Description-based recommendations are documented for English storefronts. Related collections are used when purchase-history and description recommendations are unavailable. Imported orders from another store or platform are not used by the theme recommendation algorithm.

Generated output is not a stable snapshot. Shopify says it changes frequently and can differ between Search & Discovery preview and storefront. Stores using Combined Listings also have a setting that controls whether generated recommendations show child products, parent products, or both. Before calling a result wrong, record that setting and judge the relationship, not exact preview parity.

The standard-metafield definitions document the exact keys above. Shopify’s theme recommendation guide documents the generated inputs, imported-order limitation, asynchronous rendering, and request pattern.

For a deeper explanation of candidate generation, cold start, eligibility, ranking, and set quality, use the product recommendations pillar.

Chapter 6 · Diagnostic procedure

Run the checks in an order that preserves fault isolation

Use one anchor, one expected candidate, one intent, and one storefront context through the entire procedure. If you change products halfway through, you can no longer compare the checkpoints.

1

Step 1

Freeze one reproducible test case

Owner: Investigator

Choose one anchor product and one expected candidate. Copy both numeric product IDs. Record related or complementary intent, the assigned product template, locale, cart state, and why that candidate should appear.

Pass

The expected outcome is a named product, not a vague judgment such as “better recommendations.”

Failure

The anchor, candidate, intent, or storefront context changes between checks.

2

Step 2

Verify the exact product template and module

Owner: Theme or storefront

Open the theme editor from the anchor product so Shopify loads its assigned template. Confirm the related-products section or complementary-products block exists, is visible, and is not only present on Default product.

Pass

The intended module has a visible container on the exact template used by the anchor.

Failure

The module is absent, hidden, placed on another template, or unsupported by the theme.

3

Step 3

Request native JSON before judging the theme

Owner: Developer or technical operator

On the storefront domain, open the locale-aware recommendations/products.json endpoint with the anchor ID, a limit, and the intended related or complementary intent. Save the status and returned product IDs.

Pass

A 200 response separates native candidate generation from theme rendering.

Failure

A 404 points to the anchor or Online Store publication. A 422 points to the request contract.

4

Step 4

Run every candidate through eligibility

Owner: Catalog or merchandising

Check active status, Online Store publication, price, unlisted state, gift-card state, intent-specific inventory, and whether the candidate is already in the visitor cart.

Pass

The candidate passes the rules for the current related or complementary intent.

Failure

The product is correctly excluded. Repair its state or choose another candidate.

5

Step 5

Identify the candidate source and intent

Owner: Merchandising, Search & Discovery, or app owner

Record whether the set is manual related, generated related, manual complementary, Ajax, Storefront API, or another app. For manual related products, record whether display mode is “only manual” or “ahead.”

Pass

The team can explain where each visible candidate came from.

Failure

The visible row is being attributed to the wrong system or uses the wrong intent.

6

Step 6

Compare source output with the rendered card

Owner: Theme or storefront

Capture the returned product IDs and URLs, then compare them with the DOM. Verify product and variant identity, image, price, availability, destination, heading, and card order.

Pass

The storefront preserves the candidate and its current purchasable state.

Failure

The response is correct but the renderer changes, hides, caches, or misrepresents it.

7

Step 7

Verify the exposure and click path

Owner: Analytics or storefront

Confirm the module was actually visible, click the known candidate, and inspect the destination and tracking context. Use a test cart or order only when the environment safely supports it.

Pass

The request, impression, click, candidate, position, and downstream item remain connected.

Failure

The module looks fixed but the report cannot observe the exposure or action.

Chapter 7 · API and rendering

A correct response and a correct card are separate checkpoints

Shopify’s Ajax API currently accepts a product ID, a related or complementary intent, and an optional limit from one to ten. Use locale-aware URLs. The endpoint can return product JSON or HTML rendered from a section, depending on the path. The two responses answer different questions.

Capture the request and response before reading the page. If the expected candidate is absent from the response, inspect source and eligibility. If it is present in the response and absent or wrong on the page, the failure is in rendering, filtering, caching, or card projection.

Test candidate generation

JSON endpoint

/recommendations/products.json?product_id=ID&limit=4&intent=related

Use the returned product IDs, order, availability fields, and Shopify-provided URLs to establish what the native source produced.

Test the Liquid section

Rendered HTML endpoint

/recommendations/products?product_id=ID&section_id=SECTION&limit=4&intent=related

A 404 here can mean either the anchor product or the supplied section ID was not found. Compare it with the JSON request to isolate which identity failed.

In theme code, build the request from routes.product_recommendations_url or window.Shopify.routes.root instead of hard-coding a root path. Shopify requires locale-aware Ajax URLs. The rendered section should check recommendations.performed? before it assumes the object was populated.

Shopify’s returned product URL carries pr_* query parameters used by native recommendation reports. If a custom card rebuilds the URL from the handle, it can display the right product while discarding that recommendation context. Preserve the returned URL unless you have a tested replacement measurement contract.

Observed responseWhat it establishesNext checkpoint
Products returnedThe native candidate response exists.Compare returned IDs, order, URLs, and intent with the visible cards.
Successful empty responseThe request worked but no eligible candidates survived.Inspect manual selection, automatic evidence, eligibility, and cart state.
404 product not foundThe anchor does not exist for the endpoint or is not published to Online Store.Verify anchor ID and publication before inspecting candidate relevance.
422 invalid parameterThe request is missing the product ID or uses an unsupported intent.Correct the request contract. Shopify currently accepts related or complementary.
Correct response, wrong storefrontThe failure is after candidate generation.Inspect section ID, DOM insertion, card projection, cache, variants, and URLs.

Compare one identity across response and card

Record the candidate product ID, selected or default variant, returned URL, rendered URL, image, price, availability, position, and heading. If the response carries a useful product but the card selects an unavailable default variant, candidate generation is not the first fix.

Headless storefronts use another proof surface

The Storefront API productRecommendations query accepts a product ID or handle plus RELATED or COMPLEMENTARY intent and returns up to 10 products. Shopify documents that complementary output still requires manual Search & Discovery configuration. Do not diagnose a headless row by testing only the Online Store Ajax route.

Storefront API productRecommendations reference

The exact Ajax parameters, errors, section response, and tracking URL are documented in Shopify’s Product Recommendations API reference.

Chapter 8 · Symptom playbooks

Match the observed evidence to the smallest responsible repair

The same blank rectangle can be caused by a missing section, no request, an empty candidate set, or a failed insertion. These playbooks start with evidence that can distinguish those causes.

1

Nothing appears on any product page

Proof to collect

Check the assigned templates, then look for the recommendation network request and browser error.

Interpretation

No section means placement or theme support. A section with no request means its JavaScript did not run. A request with products means insertion or rendering failed.

Smallest repair

Add or enable the native section, repair the section JavaScript, or restore the selector it expects.

2

The row appears on Default product but not another template

Proof to collect

Compare the anchor products’ template assignments and open each template in the theme editor.

Interpretation

Recommendation configuration is not the first difference. The two products are using different page compositions.

Smallest repair

Add the intended section or block to the missing template and verify it with the same anchor.

3

A manually selected related product is missing

Proof to collect

Check the selected list, related display mode, request limit, candidate eligibility, and native JSON response.

Interpretation

The selection can be filtered out by eligibility. In “ahead” mode, generated products can fill the remaining space. The theme can also request fewer products than you selected.

Smallest repair

Fix the candidate state, increase the justified display limit, or use “only manual” when exact curation is the actual requirement.

4

Related products show, but complementary products are empty

Proof to collect

Confirm complementary products are manually selected, the request uses complementary intent, and each candidate has inventory above zero.

Interpretation

Related output can be generated automatically. Complementary output requires manual configuration and has the stricter stock rule.

Smallest repair

Add complementary relationships, correct the intent, replace ineligible candidates, or add the compatible theme block.

5

Generated related products look wrong

Proof to collect

Record whether the output came from purchase history, description similarity, or related collections; inspect imported-order history, language, collections, and combined listings.

Interpretation

The preview is not a fixed ranking contract. Shopify documents that generated output changes and can differ between Search & Discovery and the storefront.

Smallest repair

Use defensible manual relationships for important anchors, improve catalog grouping, and review the parent or child combined-listing setting.

6

JSON is correct, but the storefront row is empty

Proof to collect

Compare the JSON response with the section request, returned HTML, target container, selector, and browser console.

Interpretation

Candidate generation worked. A section ID, DOM selector, insertion condition, JavaScript error, or cache is dropping the result.

Smallest repair

Repair the rendering boundary without changing recommendation data.

7

The product is right, but the image, price, variant, or link is wrong

Proof to collect

Compare product and variant fields in the response with the final card and clicked URL.

Interpretation

The card is projecting a different variant or stale product state. This is not evidence that the candidate source is wrong.

Smallest repair

Use the current response fields, choose the intended available variant, and preserve Shopify’s returned product URL.

8

The storefront works, but recommendation reports look empty

Proof to collect

Confirm the card preserves the pr_* parameters in Shopify’s returned URL, then check the report scope and date range.

Interpretation

Search & Discovery shows recommendation click rate, purchase rate, and low-engagement reporting for the last 30 days. A live page check and a reporting window are different evidence.

Smallest repair

Restore the returned tracking URL, verify the tested surface is native, and evaluate the appropriate report range before changing candidates.

Chapter 9 · Verification

Prove the repair at the same layer that failed

A theme repair is complete when the intended module renders on the intended templates. An eligibility repair is complete when the known candidate survives the native rules. A source repair is complete when the expected relationship appears in the response. A rendering repair is complete when response and card agree. A measurement repair is complete when the card preserves the native recommendation URL and the appropriate report can attribute the outcome.

Repeat the test on desktop and mobile, in a clean session and with the candidate in the cart when relevant. Then sample another anchor that uses the same template and intent. One passing product proves the controlled case, not the entire catalog.

Keep this evidence packet

Anchor and candidate IDs, intent, template, locale, market, cart state, eligibility states, candidate source, request, response, rendered card, clicked URL, report scope, owner, change, and post-fix result.

Search & Discovery currently exposes recommendation click rate, purchase rate, and products with low engagement. The in-app metrics cover the last 30 days; Shopify directs other ranges to Analytics reports. Do not treat a report as a real-time request debugger. First prove the request and link, then evaluate the documented reporting window. Shopify’s recommendation-report documentation defines the available views.

If candidates are visible and technically correct but still unhelpful, the problem has moved from delivery to recommendation quality. Use the recommendation-system guide to review shopper job, candidate generation, ranking, and set constraints. If the module is in the wrong moment, use the placement guide. If the report is the weak layer, use the recommendation analytics guide.

Review the ParticleSearch data path

Chapter 10 · Where ParticleSearch fits

ParticleSearch solves the recommendation system when the native module is the limitation

If the diagnostic proves that the theme is rendering correctly but the native candidate set, placement controls, or evidence are too limited, ParticleSearch is a direct replacement for that recommendation job. It can serve managed recommendation shelves on product and cart surfaces from the same search-ready catalogue used by the storefront search experience.

The merchant chooses the job rather than accepting one unexplained “you may also like” list. Current strategies include similar products, frequently bought together, complete the look, cart cross-sell, trending products, best sellers, and new arrivals. The shelf can have its own title and product limit, and ParticleSearch excludes the anchor or other context products so the module does not recommend the item the shopper is already considering.

Eligibility still follows store policy. Recommendations use the eligible catalogue, respect the configured sold-out and discontinued-product behaviour, and preserve the product or variant context through the shared storefront card. ParticleSearch does not make a draft product public, repair a wrong price, or decide that two products belong together when the catalogue and observed evidence do not support that relationship.

One configured surface

Product and cart placements use the same catalogue eligibility, product-card behaviour, and shopper context as the rest of ParticleSearch.

Observable outcomes

Views, clicks, empty shelves, and errors are recorded with placement and strategy context, so a weak shelf becomes evidence rather than a silent blank module.

A testable decision

Recommendation strategies can be compared on the recommendation surface, while verified order attribution remains separate from a claim of causal lift.

What the merchant no longer has to assemble

After a verified ParticleSearch launch, the team should not need one system to choose products, another card implementation to render them, and a third report to guess whether the shelf was seen. The merchant still chooses the placement, strategy, guardrails, and business interpretation. ParticleSearch owns the connected recommendation delivery and evidence path. Read the recommendation-system guide for the strategy decision and the analytics guide for the evidence contract.

Follow-up questions

Questions that should not restart the investigation

How long should I wait for Shopify product recommendations to update?
Shopify documents that generated related recommendations change frequently, but it does not publish a universal update SLA on the sources used here. Test the current API response and storefront instead of waiting an arbitrary number of hours.
Can Shopify remove a product I selected manually?
The relationship can remain configured while the candidate is filtered from the storefront because it is inactive, unpublished, unlisted, free, a gift card, out of stock under the applicable intent, or already in the visitor’s cart.
Why does the Search & Discovery preview differ from the product page?
Shopify explicitly documents that generated related recommendations can change and that the preview often differs from the storefront. Use a manual recommendation when a specific relationship must be stable.
Does an empty HTML placeholder prove recommendations failed?
No. Shopify theme recommendations are loaded asynchronously. The recommendations object is not populated during the initial section render, so the meaningful evidence is the later recommendation request and the returned section content.
Should I clear the theme cache first?
Only after the native response is correct and the storefront still shows stale output. Cache clearing cannot repair an invalid anchor, an empty eligible set, the wrong intent, or missing manual relationships.

Primary references