How to Correctly Implement Hreflang with Shopify Markets (with Code Examples)
Shopify Markets generates hreflang tags automatically for active markets - but only when your theme is configured correctly and your domain structure matches your market settings. Misconfigured hreflang is one of the top causes of international duplicate content penalties and mis-targeted search traffic for Shopify stores.
This guide walks through exactly how automatic hreflang works in Shopify Markets, where it breaks, and how to audit or override it with copy-paste Liquid code.
How Shopify Markets Handles Hreflang Automatically
When you enable Shopify Markets and assign a language and locale to each market, Shopify's Liquid theme engine outputs <link rel="alternate" hreflang="..."> tags in the <head> of every storefront page - provided your theme uses the canonical_url Liquid object and you have not manually suppressed alternate tags.
Shopify automatically sets the hreflang value using a BCP 47 language-region tag such as en-GB, fr-FR, or es-MX. It also appends an x-default tag pointing to your primary market's URL.
This works out of the box on Shopify's Dawn theme (version 13+) and most themes purchased after mid-2023. Older or heavily customized themes often strip the alternate tags during template overrides.
Domain Structure Options and Their Hreflang Impact
Shopify Markets supports three URL structures. Your choice directly affects how hreflang URLs are formed and whether Google can crawl them independently.
Structure Example Hreflang Supported Best For Subfolders example.com/fr-fr/ Yes - automatic Most stores (default) Subdomains fr.example.com Yes - requires DNS verification Regional branding Separate domains example.fr Yes - must be connected in Markets Strong geo-targeting signalCritical rule: every URL referenced in a hreflang tag must return a 200 status and must itself contain the reciprocal hreflang set. A one-sided hreflang annotation is ignored by Google.
Verifying Whether Your Theme Outputs Hreflang Tags
Before writing any code, confirm whether your theme already outputs alternate tags. Open Chrome DevTools on your storefront, go to Elements, and search for hreflang in the <head>. Alternatively, run:
curl -s https://yourstore.com/ | grep hreflang
If you see output like the block below, automatic hreflang is working:
<link rel="alternate" hreflang="en" href="https://yourstore.com/">
<link rel="alternate" hreflang="fr-FR" href="https://yourstore.com/fr-fr/">
<link rel="alternate" hreflang="x-default" href="https://yourstore.com/">
If the output is missing or shows only one locale, your theme needs manual implementation.
Manual Hreflang Implementation in Shopify Liquid
Add this snippet to your theme.liquid file inside the <head> block. It loops over every published locale in your store and outputs a correctly formatted alternate tag for each one.
{% comment %} Hreflang alternate tags for Shopify Markets {% endcomment %}
{% for locale in shop.published_locales %}
{% if locale.iso_code == shop.primary_locale.iso_code %}
<link rel="alternate" hreflang="{{ locale.iso_code }}"
href="{{ canonical_url }}">
<link rel="alternate" hreflang="x-default"
href="{{ canonical_url }}">
{% else %}
<link rel="alternate" hreflang="{{ locale.iso_code }}"
href="{{ canonical_url | replace: shop.primary_locale.root_url, locale.root_url }}">
{% endif %}
{% endfor %}
Important: shop.published_locales only returns locales you have set to Published in Settings → Languages. Unpublished locales are correctly excluded from the output.
Adding Country-Region Tags (e.g., en-GB vs en-US)
A language-only tag like en tells Google the language but not the target country. For stores with multiple English-speaking markets (UK, US, Australia), you need region-specific tags such as en-GB and en-US.
Shopify Markets exposes market-level locale data through the localization object. Use this extended snippet to output region-qualified hreflang values:
{% for market in shop.markets %}
{% if market.published %}
{% assign market_locale = market.primary_locale %}
{% assign market_country = market.countries.first %}
{% assign hreflang_value = market_locale | append: '-' | append: market_country.iso_code %}
<link rel="alternate"
hreflang="{{ hreflang_value | upcase | replace: market_locale, market_locale }}"
href="{{ market.url }}{{ request.path }}">
{% endif %}
{% endfor %}
<link rel="alternate" hreflang="x-default"
href="{{ shop.url }}{{ request.path }}">
Note: The BCP 47 standard requires the language code in lowercase and the region code in uppercase - for example, en-GB, not en-gb or EN-GB. Google tolerates case variations, but use the standard format to be safe.
5 Common Hreflang Errors on Shopify and How to Fix Them
-
Missing x-default tag
Every page needs onehreflang="x-default"pointing to the primary market URL. Add it explicitly - Shopify does not always generate it on collection or product pages in customized themes. -
Non-reciprocal annotations
Page A references Page B in hreflang, but Page B does not reference Page A. Fix by ensuring the same snippet appears intheme.liquidglobally, not only on the homepage template. -
Hreflang on redirected URLs
If your alternate URL redirects (301 or 302), Google drops the annotation. Check that all URLs listed in hreflang tags resolve to a 200 directly - use Screaming Frog SEO Spider to audit at scale. -
Duplicate tags from third-party SEO apps
Apps like SEO Manager or Plug In SEO sometimes generate their own hreflang tags. Running both creates duplicate annotations. Disable the app's hreflang output or remove the theme snippet - never run both simultaneously. -
Incorrect locale codes
Usingen-UKinstead ofen-GBis a common mistake. The UK ISO 3166-1 alpha-2 code isGB, notUK. Verify every locale code against the ISO 3166 country code list.
Validating Your Hreflang Implementation
After deployment, validate using these tools:
- Google Search Console → International Targeting report- shows hreflang errors detected during crawling. Allow 1–2 weeks for Google to recrawl after changes.
- hreflang Tags Testing Tool by Aleyda Solis (hreflang.aleydasolis.com) - paste multiple URLs and verify reciprocal tags instantly.
- Screaming Frog SEO Spider 21+- crawl your entire store and export the hreflang report to catch missing or broken annotations at scale.
Frequently Asked Questions
Does Shopify automatically add hreflang tags when I enable Shopify Markets?
Yes, Shopify generates hreflang tags automatically for published markets on themes that use the standard Liquid canonical_url object and have not had their <head> section heavily customized. Older or third-party themes built before 2023 often require manual implementation using the Liquid snippets shown above.
Should I use language-only hreflang tags (like "en") or language-region tags (like "en-GB")?
Use language-region tags whenever you target the same language across multiple countries - for example, en-US, en-GB, and en-AU. Language-only tags are acceptable when you serve a language to a single, undifferentiated global audience. For most Shopify Markets setups serving multiple regions, language-region tags deliver a stronger geo-targeting signal to Google.
What happens if my hreflang tags are not reciprocal?
Google ignores non-reciprocal hreflang annotations entirely. If Page A declares Page B as an alternate but Page B does not declare Page A, both annotations are treated as invalid. The fix is to add a global hreflang snippet to theme.liquid so every page outputs the full set of reciprocal tags automatically.
Can I use the Shopify sitemap to handle hreflang instead of head tags?
Shopify's auto-generated sitemap (/sitemap.xml) does not include hreflang attributes. You must implement hreflang either in the HTML <head> using Liquid (the recommended approach) or through HTTP headers if you control server responses - which most Shopify stores do not. Stick with the <head> implementation.
How do I troubleshoot hreflang errors shown in Google Search Console?
Start by identifying the error type: "No return tag" means non-reciprocal annotations; "Invalid language code" means a malformed BCP 47 value; "Href not indexed" means the alternate URL is returning a non-200 status or is blocked by robots.txt. Fix the root cause in your Liquid snippet, submit the affected URLs for recrawling via Search Console's URL Inspection tool, and re-check the International Targeting report after 7–14 days.
