Shopify Hydrogen SEO works when a storefront URL, its HTTP response, rendered content, metadata and product information describe the same page. A working product picker or a successful deployment does not establish that agreement.
These 14 checks help you review product, collection and localized routes before a launch or a major change. They cover the response a visitor receives, the URLs crawlers can discover and the catalog state your pages publish. Start with your actual Hydrogen version: current and legacy projects assign these responsibilities differently. The examples are documentation-based audit patterns, not results from a tested merchant store.
Identify the Hydrogen version and route sample
Check the installed @shopify/hydrogen version and the framework that serves your public pages. Shopify's current Hydrogen overview covers version 2026-10 and describes a toolkit that can work with several frameworks. Routing, rendering and SEO output belong to your application and framework.
| Project | What to verify before following an example |
|---|---|
| Hydrogen 2026-04 or earlier | The legacy project's route files, metadata helpers and template behavior |
| Hydrogen 2026-10 or later | Your framework's rendering and metadata APIs, plus Hydrogen request-handler wiring |
| A project being migrated | Both package versions and the resulting public responses; changing routers and upgrading Hydrogen are separate tasks |
The migration guide specifically removes getSeoMeta(), getSitemap() and getSitemapIndex() from the 2026-10 approach. Do not install an old snippet simply because a search result still calls it the latest Hydrogen SEO setup.
Build a small URL sample before changing templates. This fictional store uses the following cases; substitute the routes and parameter names your application actually supports.
| Sample | Purpose |
|---|---|
/products/trail-shirt |
Default product |
/products/trail-shirt?Color=Blue&Size=M |
Directly selected variant |
/collections/shirts and its next-page URL |
Product discovery |
/collections/shirts?sort=price |
A nonessential sort state |
/fr-fr/products/trail-shirt |
A localized product |
| A renamed product URL and a nonexistent handle | Redirect and missing-page behavior |
/sitemap.xml and /robots.txt |
Discovery and crawl policy |
Record the deployment revision, date, intended market and expected response for each case. Add an out-of-stock product and a product that is no longer published when those states exist in your catalog. They need separate expectations.
For merchandising and keyword basics, use the Shopify SEO guide. The checks below focus on what your custom storefront actually serves.
Check responses and server-rendered content
1. Return the right status for each route state
Request a real product, an invented handle and an old URL with a known replacement. Capture a complete GET response, including headers, rather than judging the page by its visual error message.
This example uses curl in a shell that supports backslash line continuation:
curl --silent --show-error \
--dump-header product-headers.txt \
--output product-response.html \
'https://www.example.com/products/trail-shirt'
Read the status line and any Location header before following a redirect. Then request its destination separately. A missing product should not quietly produce a 200 response with the normal product template and an apologetic message.
Distinguish an unknown handle from a catalog request that failed. Converting an upstream timeout into “product not found” can incorrectly present an existing product as gone. Investigate the failure and preserve an appropriate error response instead of inventing a replacement product.
Temporary lack of stock is different again. A useful product page can remain available with accurate availability and a genuine customer next step. Do not turn every out-of-stock item into a 404.
2. Make essential product content available in the response
Inspect the saved HTML for the product name, meaningful description, selected offer, image references and links to related pages. Text hidden inside a JSON payload is not the same as readable page content.
Then compare the response with the rendered page. Look for placeholders that never resolve, hydration that changes the selected item and content that requires a click before it exists. On a streaming framework, inspect the complete response and the rendered result; the first chunk alone can be misleading.
Google can render JavaScript, but rendering has requirements and limitations. Its JavaScript SEO guidance does not support the blanket claim that every client-rendered page is invisible, or that every server-rendered page will be indexed.
The check passes when the intended route returns an appropriate status and dependable buyer-facing content. Keep the saved response as evidence; a working component in isolation does not establish the page's actual output.
Align metadata, canonicals and product state
3. Give each route the metadata it actually describes
Compare two different products and a collection page. Each should expose the intended title, description and sharing metadata through the framework's supported head or metadata mechanism. Confirm the document head after navigation as well as on direct entry.
For current Hydrogen, these are framework responsibilities. In React Router, the route-module documentation explains both supported metadata approaches and the behavior of the meta export. If your app uses that export, the last matching route's descriptor array replaces the parent array; it is not automatically merged field by field.
That makes “the product title changed” an incomplete acceptance check. A child route might replace the title while losing a required site-level descriptor. Equally, a shared layout might keep a previous product's social image.
Write the expected values first, then compare actual output. Avoid adding a second SEO component that produces duplicate title, canonical or robots elements alongside the framework's existing implementation.
4. Choose canonical URLs by page purpose
Separate three types of URL state: tracking parameters, product selections and a different slice of a collection. Removing every query string treats all three as equivalent.
| URL state | Decision to verify |
|---|---|
| Tracking-only copy of a product | Consolidate with the intended clean product URL |
| A selected variant on a single product page | Follow the store's documented parent/variant canonical policy |
| A genuinely separate variant landing page | Preserve its intended identity and distinct content |
| A collection's next page | Keep the distinct page URL; do not automatically canonicalize it to page one |
For each sample, inspect the actual rel="canonical" element. Check its scheme, production host, path, locale and any parameter that is essential to that identity. Compare internal links and sitemap entries with the same decision.
Google's canonical guidance explains consolidation signals. A declared canonical is a signal, not a command or proof that Google selected it.
5. Open variant URLs directly
Copy a blue medium product URL into a fresh request. Does it actually load blue, medium, the corresponding image, the right price and the correct purchase availability?
Shopify's current variant guide reads selected options from the request and resolves the matching variant. A picker that changes browser state is insufficient if the copied URL later opens a different selection.
Also check old Liquid-style ?variant= links where they still receive traffic or appear in feeds. Current Hydrogen request handlers include conversion of those product links to option parameters; confirm your framework wiring and actual destination rather than assuming a legacy link survives automatically.
Canonicalization and selection are separate checks. A variant URL may correctly select an item for a customer while intentionally pointing its canonical at the parent product. Do not break that customer link merely to remove an indexing-report exclusion.
6. Match structured data to the visible offer
Compare product identity, currency, price and availability across the displayed page, the underlying catalog record and the JSON-LD. Repeat for a second variant and another market where applicable.
The goal is accurate product representation. For variant families, Google documents ProductGroup and Product markup, including different treatment for single-page and separate-page designs. Do not make every option combination look like an independent product page unless that reflects your storefront.
Check that the image and offer describe the selected product state and that review information actually exists. Validate representative URLs with the Rich Results Test and investigate discrepancies in the rendered output. Passing markup validation establishes neither a guaranteed rich result nor a ranking improvement.
Make collection and market routes discoverable
7. Expose the next collection page through a real link
Find a product that appears beyond the first group of collection results. Starting from the collection URL, follow the next-page links until you reach it. Each destination should work when requested directly.
An infinite-scroll interaction can coexist with those URLs, but a button that only changes client state is not an equivalent discovery path. Google's pagination guidance recommends distinct URLs and crawlable links; Googlebot generally does not click interface controls to reveal more products.
For example, a fictional collection using page numbers might expose:
<a href="/collections/shirts?page=2">Next shirt collection page</a>
Your Hydrogen app may use cursors instead. Preserve the parameters needed to fetch that slice, and verify that a copied next-page URL produces the expected products. Do not apply an arbitrary “noindex everything after page two” rule.
The broader ecommerce category-page guide helps with useful category content. Here, the acceptance condition is a dependable path to deeper products.
8. Give filters and internal search an explicit policy
Inventory parameter combinations your interface actually generates. Include sort order, color, size and internal searches. Decide which states are useful public landing pages and which are only browsing utilities.
A collection created for a genuine search need requires stable content, deliberate internal links and its own appropriate identity. A temporary price-sort state usually needs a different treatment. Avoid letting each filter permutation inherit a successful, indexable page by accident.
Inspect both robots metadata and response headers. If you use noindex, the crawler must be able to fetch the page to read it. Blocking that same URL in robots.txt can prevent the intended instruction from being seen. Google's robots metadata specification documents these controls.
Do not treat every URL excluded from indexing as an error. Judge it against the policy you wrote for that state.
9. Keep each market's URL and content together
Request a localized product directly, with no existing browser session. Confirm the language, currency, availability and links belong to that market. A French route that silently publishes the default market's offer has failed even if its translation looks correct.
Hydrogen's Markets documentation covers resolving the market and passing the corresponding context into queries. Hreflang is a separate page-output responsibility.
Where you publish equivalent language or regional pages, check their canonical decisions and reciprocal, self-inclusive alternate links against Google's localized-page guidance. Keep valid translated pages accessible; do not canonicalize all of them to the default-language page simply to reduce the URL count.
Verify sitemap, robots and redirect routes
10. Compare the sitemap with the routes you intend to index
Fetch the sitemap from the actual public storefront host. If it is an index, open the child files as well. Compare their URLs with the route sample and the catalog's intended public inventory.
Look for missing collections or editorial pages, preview hosts, stale handles and URLs that redirect elsewhere. Check a recently published product and a recently unpublished product after the documented cache window. Keep a temporarily out-of-stock product when its page remains a useful, intended search destination.
Current Hydrogen's sitemap migration instructions require your own queries and XML responses. A previous starter's helper call is not evidence that a current storefront includes every route or paginates the catalog completely.
Use absolute canonical URLs and a meaningful lastmod when you can maintain it accurately. Google's sitemap documentation limits a file to 50,000 URLs or 50MB uncompressed. Split larger inventories appropriately and verify the last page of each catalog query, not only the first response.
An XML file that parses successfully can still be incomplete.
11. Read the crawl settings on the correct environment
Check /robots.txt, page-level robots tags and X-Robots-Tag headers on the final production domain. Compare them with the intended index policy. A public collection should not inherit a preview-wide restriction when the deployment becomes live.
Also inspect a preview separately. It is a different host and may have different access controls. Robots directives are not authentication and should not be the only protection for private content.
For legacy Oxygen projects, the legacy SEO documentation describes environment-specific robots behavior and default caching. Treat those as version- and hosting-specific details. Do not promise the same behavior or a universal 24-hour refresh in every current Hydrogen application.
If the page is accidentally marked noindex, find the rule that emits it. Adding an index value elsewhere does not establish that the conflicting restriction disappeared.
12. Exercise old URLs through the redirect path
Prepare a short map of important old product, collection and content URLs to their intended destinations. Request each original URL, inspect its redirect, then request the final page. Confirm the final page's canonical and content match the replacement.
In current Hydrogen, request handlers run Shopify-owned routes before your framework router and check Shopify URL redirects after a 404. An overbroad catch-all that returns a successful page for every path can prevent that redirect lookup from running.
Check renamed routes, locale prefixes and legacy variant links where they matter. Avoid routing all removed products to the homepage. A replacement needs to serve the original visitor's purpose; otherwise an honest missing-page response may be more appropriate.
The redirect check passes when the expected source reaches the intended replacement without a loop or unnecessary chain. The existence of a redirect record in the admin alone is insufficient.
Recheck catalog freshness and route performance
13. Verify that catalog updates reach the whole page
For a controlled update on a storefront you are authorized to change, record a before-and-after value. A description revision is often easier to trace than an inventory change. Request the same URL again after the application's expected refresh or invalidation process.
Compare the visible content, title, description, structured data and selected offer. If only one surface updates, trace its data and cache path. A refreshed JSON-LD block alongside an old displayed price is still inconsistent.
Repeat the request for another product, then return to the original. Where markets differ, request each market independently. This helps expose data reused across the wrong product or locale.
Write down the expected freshness window before deciding the result is stale. Use the actual cache configuration and publication workflow, rather than borrowing a default from another Hydrogen generation. Also distinguish the page's freshness from the sitemap's refresh: neither one proves the other.
14. Measure performance on representative route states
Check a product, a substantial collection and a product with complex option selection. A fast homepage does not establish that those templates work well.
Inspect whether the main product image is appropriately sized, whether space is reserved for images and whether nonessential scripts delay useful interaction. Trace slow catalog queries and loading boundaries instead of assuming that a headless build is automatically faster.
Core Web Vitals cover loading, responsiveness and visual stability through LCP, INP and CLS. Keep field observations separate from lab measurements. A small or new storefront may have no usable field data; label it unavailable and retain a repeatable lab baseline rather than calling that a field-data pass.
Record the URL, device profile, tool, date and relevant state with each measurement. Compare like-for-like runs after a change. Neither a high score nor server rendering guarantees search rankings, and a poor result needs diagnosis rather than a platform-wide conclusion.
Keep a release record for every check
Copy this CSV into your release notes or spreadsheet. It starts with unverified outcomes deliberately. Fill in an actual URL, market, observed result and evidence file for each row; duplicate rows for additional route samples.
check_id,check,url,market,revision,outcome,evidence,next_action
1,HTTP state,,,,unverified,,
2,Rendered content,,,,unverified,,
3,Route metadata,,,,unverified,,
4,Canonical identity,,,,unverified,,
5,Variant direct link,,,,unverified,,
6,Product structured data,,,,unverified,,
7,Collection pagination,,,,unverified,,
8,Filter and search policy,,,,unverified,,
9,Market consistency,,,,unverified,,
10,Sitemap coverage,,,,unverified,,
11,Robots and environment,,,,unverified,,
12,Legacy redirects,,,,unverified,,
13,Catalog freshness,,,,unverified,,
14,Route performance,,,,unverified,,
Use pass when the observed output matches the route's stated expectation, fail when it contradicts it, and unverified when evidence is missing. Record not applicable with a reason for a state the storefront does not support.
Block a release on essential defects such as missing product content, incorrect canonicals, unintended noindex or broken important redirects. Give less urgent improvements an owner and a concrete next action. Save the previous revision's evidence so the next change has a meaningful comparison.
Screpy, which publishes this guide, offers Website Audit to group recorded findings for metadata, canonicals, links and status codes. Use that crawl evidence to find affected URLs and compare a recrawl after a repair. Inspect framework behavior and market-specific product state separately; a crawl finding alone cannot establish which application branch ran or what Google indexed.
The finished record should explain what was checked, what remains uncertain and why the storefront is ready for its intended routes. Measure indexing and search performance separately after launch.