Hreflang Manager documentation
How the app works, what it does on each page, and what the audit checks. For quick setup steps and common questions, see support.
On this page: Overview · Plans · Setup · The market map · Which pages get tags · Keeping tags up to date · The audit · Audit findings · Setup checklist states · Password-protected storefronts · Troubleshooting · Limits · Data and uninstalling
Overview
Hreflang tags tell search engines which version of a page to show to which language and region. Hreflang Manager reads your markets, languages and translated URL handles from Shopify, and adds one set of hreflang tags to each storefront page through a theme app embed. A separate audit fetches a sample of your live pages and checks the tags against Google's guidelines.
What it doesn't do: it doesn't translate content, create markets, change your URLs, or promise better rankings. It covers one Shopify store and its markets; it doesn't link separate stores.
Plans
| Free | Pro | |
|---|---|---|
| Market map and setup checklist | Yes | Yes |
| Audit of your live pages | When you run it | When you run it, and every week |
| Hreflang tags on your storefront | No | Yes |
Pro has a 14-day free trial. Development stores get every Pro feature at no charge. Current prices are on the Shopify App Store listing.
On Free, the app adds no hreflang tags. Keep Shopify's own automatic hreflang tags turned on while you're on Free, so your store still has hreflang. The setup checklist says so on step 2. If you move from Pro to Free, the app stops adding its tags and you should turn Shopify's automatic tags back on.
Setup
- Install the app and approve the permissions. All are read-only: markets, languages, translations, products, content and publications.
- Turn on the app embed. Click Enable app embed in the setup checklist. It opens the theme editor with the embed selected; click Save.
- Turn off Shopify's automatic hreflang tags (Pro). Click Open Preferences, or go to Online Store > Preferences, untick Automatic hreflang tags and save. Shopify's storefront cache can take a few minutes to drop its tags.
- Check the market map. One row per hreflang code the app publishes (see below).
- Run an audit and fix what it reports.
The market map
The market map is the list of hreflang codes the app publishes, each with the root URL it points to. It's shown on the app's home page with the market, language, hreflang code and root URL of each row. It's built like this:
- Markets: only active markets that serve one or more countries count. Business-to-business and retail markets don't serve the online store, so they're left out.
- Where each market lives: a market's own domain or subfolder (for example
/fr-caorfr.your-store.com). A market without one is served from your primary domain. - Languages: every published language of each market. Unpublished languages are skipped.
- Codes: each language gets a code per country the market serves, such as
en-CAandfr-CA, for up to 10 countries. Your primary domain also gets plain language codes such asenandfr. A market with more than 10 countries gets plain language codes only, and only where no other market already uses them. - One URL per code: if two markets would claim the same code, the app keeps one and shows a warning on the map.
- x-default: your primary domain in its primary language.
For example (simplified), a store with English and French on its primary domain (United States) and a Canada market at /en-ca and /fr-ca gets these tags on a product page:
<!-- hreflang-manager:start -->
<link rel="alternate" hreflang="en" href="https://your-store.com/products/snowboard">
<link rel="alternate" hreflang="en-US" href="https://your-store.com/products/snowboard">
<link rel="alternate" hreflang="fr" href="https://your-store.com/fr/products/planche">
<link rel="alternate" hreflang="fr-US" href="https://your-store.com/fr/products/planche">
<link rel="alternate" hreflang="en-CA" href="https://your-store.com/en-ca/products/snowboard">
<link rel="alternate" hreflang="fr-CA" href="https://your-store.com/fr-ca/products/planche">
<link rel="alternate" hreflang="x-default" href="https://your-store.com/products/snowboard">
<!-- hreflang-manager:end -->
The comments mark the app's tags, so you (and the audit) can tell them apart from tags added by the theme, Shopify or another app.
Which pages get tags
Every storefront page gets tags, except pages that shouldn't be in search: the 404 page, search results, the cart, the password page, gift cards and customer account pages. On those the embed prints <!-- hreflang-manager:skip --> and no tags.
On each page, each alternate URL is the same page in the other market or language:
- Translated handles. Products, collections, pages, blogs and blog posts with a translated handle get alternates that use it (
/fr/products/planche, not/fr/products/snowboard), so alternates don't point at redirects. Blog posts use their blog's translated handle too. - Market availability. A product that isn't sold in a market's countries is left out of that market's alternates, so they don't point at a page that returns "not found".
- Products opened from a collection (
/collections/x/products/y) get the product's own URLs. - Anything after the page's path, such as a collection tag filter, is kept on each alternate.
Keeping tags up to date
- Products and collections: updated within minutes of a change, through Shopify's notifications.
- Pages, blogs, blog posts and translations: Shopify doesn't send notifications for these, so changes are picked up by the daily sync (about once every 24 hours), or straight away when you click Refresh in the app.
- Markets, domains and languages: picked up by the daily sync or by Refresh on the market map.
The app's Per-page sync section shows the last full sync, and lists the products, collections and pages with translated handles or limited market availability.
The audit
The audit fetches a sample of your live storefront the way a search engine would, and checks the hreflang tags on each page and between pages.
- What it checks: up to 60 URLs. First the home page of every market and language, then complete sets of alternates (every language and market version of one page) for up to 3 collections, 4 products, 2 pages and 2 blog posts. Pages with translated handles or limited availability go first, because they're where problems are most likely.
- Linked alternates: alternate URLs that weren't in the sample are checked once each (up to 40), to see whether they answer, redirect, or are marked noindex.
- robots.txt: respected. Pages your robots.txt blocks for the audit aren't fetched; the count of skipped pages is shown. If robots.txt returns a server error or doesn't answer, the audit stops.
- Redirects are reported, not followed.
- How it identifies itself:
GoodkeelHreflangAudit/1.0 (+https://goodkeel.com/hreflang-manager/). - When it runs: whenever you click Run audit, and every week on Pro. A run takes a minute or two.
Results are grouped by problem, worst first. Each problem shows how many pages it affects, an example, the fix, and its basis: Google's published guidelines, or common best practice.
Audit findings
| Finding | What it means | Basis |
|---|---|---|
| Tags outside the page head | Some hreflang tags are in the page body, where Google ignores them. Usually markup injected higher in the head closes it early. | |
| Alternate URLs that aren't full URLs | An alternate has no protocol and domain. Alternates must be full URLs. | |
| Invalid language or country codes | A code isn't a valid language, or language and region, code. | |
| Pages that don't list themselves | A page lists its other versions but not its own URL. | |
| Missing return links | Page A lists page B, but B doesn't list A, or the two disagree about which language is which. Google ignores one-way pairs. | |
| Canonical points elsewhere | A page with hreflang tags, or one of its alternates, has a canonical pointing to a different URL. Alternates should be canonical pages. | |
| One code, several URLs | The same code points to different URLs on one page. | Best practice |
| Conflicting x-default | A page has more than one x-default, or pages in the same set name different x-default pages. | Best practice |
| Tags from more than one source | The page has the app's tags and tags from Shopify's automatic setting, the theme or another app. | Best practice |
| Alternates that redirect | An alternate URL redirects. Alternates should point straight at the final URL. Usually a changed handle. | Best practice |
| Alternates that return an error | An alternate URL returns an error such as 404, so it can't link back. | Best practice |
| Alternates marked noindex | An alternate page tells search engines not to index it, so it won't be shown to that audience. | Best practice |
Google's guidelines: Tell Google about localized versions of your page.
Setup checklist states
Steps 1 and 2 are checked by reading your storefront home page the way a visitor does. The result is kept for 10 minutes; Check again reads it at once.
- App embed is on: the home page carries the app's marker comment.
- App embed not found on your home page: switch the embed on in the theme editor and click Save, then Check again.
- No other hreflang tags found: only the app's tags are on the home page.
- Still on: N other hreflang tags: Shopify's automatic tags, the theme or another app still add tags.
- Pro only: keep Shopify's tags on while you're on Free: see Plans.
- Can't check: the storefront didn't answer, redirected too many times, or returned an error. The reason is shown.
Password-protected storefronts
If your storefront has a password, the setup check and the audit stop at the password page. Save the storefront password in the app's Storefront password section and they open your store the way a visitor does. The password is stored encrypted, sent only to your own storefront, never shown back or logged, and you can remove it at any time. Or remove the password in Online Store > Preferences.
Troubleshooting
My pages have no hreflang tags from the app
View the page source and look for a comment starting with hreflang-manager:
- No comment at all: the app embed is off, or the theme editor change wasn't saved.
hreflang-manager:free: the store is on the Free plan, which adds no tags.hreflang-manager:skip: this kind of page never gets tags (see Which pages get tags).
The audit says tags come from more than one source
Turn off Online Store > Preferences > Automatic hreflang tags, remove any hreflang snippet from the theme, and turn off hreflang in other apps (some translation apps add their own). Then run the audit again.
A translated URL in the tags is out of date
Translations of pages, blogs and blog posts are picked up by the daily sync. Click Refresh to update at once.
An alternate returns "not found"
Check the product is active and available in that market's catalog, then click Refresh. Collections are always listed for every market (see Limits).
The audit stopped early
The reason is shown. Usually robots.txt couldn't be read, or the storefront has a password (see above). Run it again once fixed.
Limits
- One store and its markets. Separate Shopify stores aren't linked.
- Regional codes for up to 10 countries per market; markets with more get plain language codes.
- Market availability is checked for products only, in up to 50 countries. Collections, pages and blog posts are listed for every market.
- Market-specific handle translations aren't read; the language's translated handle is used.
- The audit checks a sample, not every page.
- The market map has a size limit. Stores with very many markets and languages may lose regional codes first; the app shows an error if it can't fit.
Data and uninstalling
The app keeps your store's domain and access token, the alternate URLs it works out, your audit results, and your storefront password if you save it (encrypted). Nothing about your customers. When you uninstall, the embed and its tags go with the app and we delete your store's data. Turn Shopify's automatic hreflang tags back on so your store still has hreflang. See the privacy policy and the changelog.