Hreflang in Joomla: telling Google which language version to show
Joomla writes hreflang tags itself once the Language Filter plugin has them switched on and every translation is linked through associations.
A site in Dutch and English goes live. A month later the Dutch pages show up in Google for people searching in English, and the English home page ranks in the Netherlands while the Dutch one is nowhere. Nothing is broken. Google simply has two pages that look alike and no information about which one belongs to which reader.
That information is what hreflang is for. Joomla can write those tags for you without an extension, but only when two settings are switched on and the translations are linked to each other. Most multilingual sites skip the second part.
What the tags look like
In the <head> of each page, one line per language version, including the page itself:
<link href="https://example.com/nl/diensten" rel="alternate" hreflang="nl-NL">
<link href="https://example.com/en/services" rel="alternate" hreflang="en-GB">
<link href="https://example.com/en/services" rel="alternate" hreflang="x-default">
Google reads this as: these URLs are the same page in different languages, show the Dutch one to Dutch searchers, the English one to English searchers, and the x-default one to everybody else. The tags do not boost rankings. They decide which of your own pages appears.
Step 1: the Language Filter plugin
Go to System > Plugins and open System - Language Filter. It is already enabled on any multilingual site, otherwise the language prefixes in your URLs would not work. Check these options:
- Item Associations: Yes. Without this, the Associations tab does not appear in the editors and nothing below works.
- Add Alternate Meta Tags: Yes. This writes the
rel="alternate" hreflanglines. - Add x-default Meta Tag: Yes, and set x-default Language to the language you want visitors from other countries to land on. For most sites that is English, not the site's default language.
Save and look at the source of your home page. You should see one alternate line per published content language. Home pages are linked automatically, so this is the one place where it works straight away.
Step 2: associations, page by page
For every other page, Joomla only knows that the Dutch article "Diensten" and the English article "Services" are the same page if you tell it. Open the Dutch article, go to the Associations tab and pick the English article in the English field. Save. The link works in both directions, so you do not have to repeat it from the English side.
Associations exist for articles, categories, menu items, contacts and newsfeeds. Associate the menu items as well as the articles. Most pages are reached through a menu item, and the Language Filter looks at the association of the item that produced the page.
For a site with more than a handful of pages, use Content > Multilingual Associations. Choose an item type and a reference language and you get a list with a column per language that shows what is linked and what is missing. Clicking a missing language opens the source and target side by side, so you can create the translation and associate it in one go.
What goes wrong
Unassociated pages get no useful tags. An article without associations has no other language versions as far as Joomla knows, so no alternate set is written. Google then treats the Dutch and English versions as unrelated pages and picks one on its own. This is the most common situation on sites that were made multilingual after launch.
Content set to "All" languages. An article with the language field set to All has no translations to associate. It is shown under every language prefix, which also gives you the duplicate URL problem. Give each page a real language and a translated counterpart, or accept that it will not get hreflang.
The canonical points to the other language. Each language version has to name itself as canonical. If an SEO extension or a template override sets the canonical of /en/services to /nl/diensten, you have told Google the English page is a copy, and it will drop it. Hreflang and canonical must agree.
Unpublished or restricted targets. If the associated translation is unpublished, or only visible to registered users, the tag points to a page Google cannot see. Check the targets before you blame the plugin.
A cached page from before you made the change. With page caching on, old HTML without the tags can be served for a while. Clear the cache under System > Clear Cache after you change the plugin settings.
How to check it
Open a translated page, view the source and search for hreflang. Then open each URL in the list and confirm that it lists the same set back. Google ignores pairs that are not confirmed from both sides, so one missing association breaks the link for that page in both directions.
Search Console no longer has a separate report for international targeting; Google retired it in 2022. Use the URL Inspection tool on a few translated pages to see which version Google has chosen as canonical, and an external crawler for a full check of the site. Once a crawler finds no pages with missing return links, you are done.
If you set up the languages in the wrong order, start with the multilingual basics first. Hreflang only works on a site where every language has its own home page, content language and menu.
Doctor Joomla is a project of Cloudfaction, a Dutch agency building and maintaining Joomla sites since 1999. The articles are made with the help of AI, so tell us if something does not match your screen. Mail info@cloudfaction.nl if you want someone to look at yours.