On WordPress, hreflang tags are added for you. Enable a language and its pages start declaring each other as alternates, which is the part of multilingual SEO people most often get wrong by hand.
What the tags do
An hreflang tag tells a search engine that two URLs are the same page in different languages. Without them, /pricing/ and /es/pricing/ look like competing pages with similar content. With them, they read as one page in two languages, and each gets served to the right audience.
Real output on a page in a project with Spanish (Spain) and French (France) added, from an English (US) source, looks like this:
<!-- Universally hreflang tags -->
<link rel="alternate" hreflang="en-us" href="https://example.com/pricing/" />
<link rel="alternate" hreflang="es-es" href="https://example.com/es/pricing/" />
<link rel="alternate" hreflang="fr-fr" href="https://example.com/fr/pricing/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/pricing/" />
Three things to note in that: every language is declared with its full region code rather than a bare es or fr, the source language gets an alternate of its own, and an x-default line points at the source URL.
What you get without configuring anything
Tags that follow your languages. Add a language and it joins the set. Remove one and it drops out. There is no list to maintain and nothing to regenerate after a change.
URLs that match your structure. Each alternate points at the language's real URL, built from the segment you configured. See Add and remove languages.
Region codes, not bare language codes. Every language is stored with a region, and that is what is declared. See Language variants and regional targeting.
Two cases where a tag points somewhere it should not
Both are worth knowing if you are auditing your own markup:
- A disabled language is still declared. Disabling hides a language from the switcher, but the alternate link for it is still emitted, and the URL no longer serves a translation. If search engines must not see a language, remove it rather than disabling it. See Add and remove languages.
- An excluded page still declares alternates. A path under Exclude Pages gets alternate links for every language, and each of those URLs redirects back to the source page. See Exclude pages.
Checking them
View source on a translated URL and look in the <head> for the <!-- Universally hreflang tags --> comment, followed by rel="alternate" lines. Expect one per language, plus one for your source language, plus x-default: three languages means five links.
Google Search Console's International Targeting report is the slower but more thorough check, since it reports mismatches rather than just presence.
Tags are added independently of translation, so a page that is not translated, or is excluded, still gets them. If they are missing entirely, the cause is one of these:
- The site is not connected, or its API key is missing or invalid
- Universally could not be reached when the language list was last fetched, so the list is empty. Use Refresh under Universally » General » Languages, which can take up to 15 minutes to expire on its own
- Your theme does not call
wp_head(), so nothing in the<head>is added by any plugin
If you have your own SEO plugin
Universally does not touch hreflang links that are already in your markup: an element carrying an hreflang attribute is excluded from link localization, so whatever your SEO plugin wrote is what ships. If you would rather it owned the tags entirely, that keeps working.
Through the API
An API integration serves its own pages, so it emits its own <head>. Universally supplies the translated content and the URL structure; adding the alternate links is part of the integration. See Integrate using the API.