Reciprocity is the whole mechanism
Hreflang works by cross-confirmation. Page A claims page B is its Russian version; page B must claim page A is its English version. If either side is missing, a crawler cannot verify the relationship and drops the annotation for that pair.
This is why hreflang so often does nothing despite being present: the tags were added to the main language and not to the translations.
The four mistakes worth checking for
- No self-reference. Each page must list itself alongside the others.
- Relative URLs. Ignored silently. Always absolute, with the scheme.
- A wrong code.
RUuppercase,en_GBwith an underscore,uafor Ukrainian (which isuk). All ignored. - No x-default. Not fatal, but it leaves the choice to the crawler for every visitor you have no page for.
Where to put it
In the <head>, in the HTTP headers, or in the sitemap — all three are valid
and you only need one. The head is easiest to inspect and hardest to forget,
which is why the tool produces link tags.
For a two-language site the block is three lines and never changes. Put it in your layout so it cannot drift out of sync.
Questions
Why must every page list itself?+
Because hreflang is a set of mutual declarations, and a crawler verifies them. If your English page lists the Russian one but the Russian page does not list back, the whole annotation is discarded — not partially applied, discarded. A self-reference is part of that mutual set.
What is x-default for?+
The page shown to anyone whose language you do not have. It is where a Portuguese speaker lands when you offer English and Russian. Without it, search engines guess, and they usually guess the page they crawled first rather than the one you would choose.
Should the code be language or language-region?+
Language alone unless the regional versions genuinely differ — different prices, different legal text, different stock. `en-GB` and `en-US` for a site with one English version splits your own pages against each other for no gain.
Do the URLs have to be absolute?+
Yes. A relative hreflang href is ignored entirely, and it is one of the most common reasons an otherwise correct block does nothing. The tool flags it.