georgebakoulis.dev

Polylang Already Handles Your Hreflang Tags

I accidentally doubled the hreflang tags on every page of worldtravellen.com.

I was expanding the site beyond Greek and added a custom function in the theme that looped through Polylang's languages and printed <link rel="alternate" hreflang="..."> tags manually. It looked like a reasonable SEO improvement. It wasn't. The code introduced two problems, and both hurt search rankings instead of helping.

Here's what was actually happening.

It duplicated what Polylang already does

Polylang outputs hreflang tags automatically through wp_head(). That's built-in behaviour, not a plugin add-on you need to supplement. The custom code ran after wp_head(), so every page ended up with two sets of hreflang tags. Google sees duplicate hreflang and doesn't know which set to trust. Instead of clean language signals, you get confusion.

It pointed every page to the homepage

The function used pll_home_url($lang) to build the alternate URLs. That function returns the homepage URL for each language. So on /en/travel-tips/vienna/, the hreflang tags pointed to / and /el/ instead of the actual translated post. Google would see every single page on the site claiming its alternate version is the homepage. That's not a subtle mistake. That's telling search engines your entire site has one page.

The takeaway

Polylang handles hreflang correctly out of the box. It outputs per-page alternate URLs through wp_head(), pointing to the actual translated version of each page. Manual hreflang code on top of that doesn't add a safety net. It adds duplicate tags and wrong URLs. If you're running Polylang, check your theme for custom hreflang functions. If you find one, remove it.