No Code Attached Yet bug
avatar hikashop-nicolas
hikashop-nicolas
12 Oct 2023

Steps to reproduce the issue

On a Joomla website with multilanguage setup ( https://docs.joomla.org/J3.x:Setup_a_Multilingual_Site ), activate the "Add alternate meta tags" setting of the Language Filter plugin.
This means that on the pages available in different languages on the frontend, the plugin will add an alternate link meta tag for each language.
However, it also adds the link tag for the current language. This is not necessary (actually I think it shouldn't be the case https://moz.com/learn/seo/hreflang-tag ) and due to the way the Document class is written, it backfires in some cases.
For example, if an extension adds a canonical link tag to the header for the current page (it is best practice as far as I know : https://www.lumar.io/blog/best-practice/canonical-tags-easy-dos-donts/#:~:text=All%20pages%20(including%20the%20canonical,to%20prevent%20any%20possible%20duplication. ) before the Language Filter plugin runs in onAfterDispatch, the Language Filter plugin will overwrite the canonical link tag to a hreflang tag for the current language.

Expected result

On the page of the relative URL collection/lady-datejust/lady-datejust-279138rbr-0015 which uses the en-US language, I want to have:
<link href="https://xxx.com/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="canonical">
<link href="https://xxx.com/fr/rolex/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="alternate" hreflang="fr-FR">

Actual result

<link href="https://xxx.com/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="alternate" hreflang="en-US">
<link href="https://xxx.com/fr/rolex/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="alternate" hreflang="fr-FR">

System information (as much as possible)

I tested it on Joomla 4 and Joomla 5rc2 with the latest version of HikaShop but I think it would be the same on a Joomla article page available in different languages with an extension adding a canonical tag to it before the onAfterDispatch event.

Additional comments

This is an issue that was reported on our forum:
https://www.hikashop.com/forum/product-category-display/907095-issue-ith-canonical-urls.html

I think it can be fixed by changing the line:
$language->link = Route::_($currentInternalUrl);
to:
unset($languages[$i]);
in the Language Filter plugin's onAfterDispatch function in order to skip the current language.

avatar hikashop-nicolas hikashop-nicolas - open - 12 Oct 2023
avatar joomla-cms-bot joomla-cms-bot - change - 12 Oct 2023
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 12 Oct 2023
avatar brianteeman
brianteeman - comment - 18 Oct 2023

However, it also adds the link tag for the current language.

I agree that seems to be wrong/bug

Correction after looking at the spec it has to exist on all the languages see https://developers.google.com/search/docs/specialty/international/localized-versions#common-mistakes

avatar Sandra97
Sandra97 - comment - 18 Oct 2023

Main issue here is that when "Add alternate meta tags" is on yes, it makes the canonical tag disappear

avatar brianteeman
brianteeman - comment - 18 Oct 2023

Main issue here is that when "Add alternate meta tags" is on yes, it makes the canonical tag disappear

as it should

avatar Sandra97
Sandra97 - comment - 18 Oct 2023

So it's expected to not have the alternate href of the other language when you have the canonical URL tag?
On another site, both the canonical tag and the href tags are there. I'm lost

avatar brianteeman
brianteeman - comment - 18 Oct 2023

The canonical tag in joomla refers to a canonical domain not a canonical url

rel=alternate is like saying that the url is a soft canonical url for that language

avatar Sandra97
Sandra97 - comment - 18 Oct 2023

Easier if I explain with an example.

I'm supposed to have in my source code:

<link href="https://xxx.com/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="canonical">
<link href="https://xxx.com/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="alternate" hreflang="en-US">
<link href="https://xxx.com/fr/rolex/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="alternate" hreflang="fr-FR">

But I have this:

<link href="https://xxx.com/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="alternate" hreflang="en-US">
<link href="https://xxx.com/fr/rolex/collection/lady-datejust/lady-datejust-279138rbr-0015" rel="alternate" hreflang="fr-FR">

After doing some tests, I noticed that if I disable Add Alternate meta tags, the canonical link is back (but of course it's not a solution).

avatar hikashop-nicolas
hikashop-nicolas - comment - 18 Oct 2023

However, it also adds the link tag for the current language.

I agree that seems to be wrong/bug

Correction after looking at the spec it has to exist on all the languages see https://developers.google.com/search/docs/specialty/international/localized-versions#common-mistakes

Note that what is written there is not the same. What it says is that if [page EN] has a hreflang tag to [page FR], then [page FR] has to have a hreflang tag to [page EN]. I completely agree with this.

The problem pointed at here is that [page EN] has a hreflang tag to [page EN] (itself), which also has the side effect of removing the canonical tag.

avatar hikashop-nicolas
hikashop-nicolas - comment - 25 Oct 2023

I think I found the solution to this issue. The line:
if($i !== $this->current_lang)
needs to be added before the line:
$doc->addHeadLink($server . $language->link, 'alternate', 'rel', ['hreflang' => $i]);
in the file plugins/system/languagefilter/src/Extension/LanguageFilter.php

That way, the language filter plugin will skip adding the hreflang tag for the current language and only add it for other languages.

avatar brianteeman
brianteeman - comment - 25 Oct 2023

and that would be wrong as stated before at the link I shared from google

If page X links to page Y, page Y must link back to page X.

Or have I misunderstood that statement?

avatar hikashop-nicolas
hikashop-nicolas - comment - 25 Oct 2023

I agree with that statement. But we're not talking about this here.
The problem I'm talking about is that at the moment page x is linking to both page x and page y, and that page y is linking to both page x and page y.
My proposed change make it so that page x only links to page y, and that page y only links to page x.
I hope it is more clear.

avatar hikashop-nicolas
hikashop-nicolas - comment - 20 Nov 2023

Note that we found the solution to this problem:
https://www.hikashop.com/forum/product-category-display/907095-issue-ith-canonical-urls.html#356157
It's been tested for several weeks and after this change, everything works as expected.

avatar Hackwar Hackwar - change - 27 Mar 2024
Labels Added: bug
avatar Hackwar Hackwar - labeled - 27 Mar 2024
avatar MacJoom
MacJoom - comment - 10 Apr 2025

Hi @hikashop-nicolas - thank you for your contribution - would you like to do a PR for the fix in Joomla? Otherwise i can do it.

avatar hikashop-nicolas
hikashop-nicolas - comment - 10 Apr 2025

Hi, and thanks for coming back to it.
Please make the PR if you can. I don't have the setup on my local machine to do it easily.

avatar MacJoom
MacJoom - comment - 3 May 2025

My Research has shown that it is recommended to have the link tag with rel="alternate" hreflang="en-US" even on the page with the same language (self referencing) and even if there is a canonical tag, but only if translated pages exist. My tests showed that if you have a canonical tag, the hreflang tag is gone, which seems to be wrong. @hikashop-nicolas: I don't think your solution is correct.

avatar hikashop-nicolas
hikashop-nicolas - comment - 3 May 2025

Yes, the solution I proposed is to keep the canonical tag and not add the self referencing hreflang tag to avoid overriding the canonical tag. If you want to keep both, that's indeed not the solution you want.

A solution to be able to keep both would require changing the way HtmlDocument is written: https://github.com/joomla/joomla-cms/blob/5.3-dev/libraries/src/Document/HtmlDocument.php
That's because both the canonical URL and the self referencing hreflang tags normally need to use the URL of the current page and HtmlDocument uses the URL of the tag as key of the array. Which means that without changing HtmlDocument, you can't have both tags at the same time on a page.

And changing HtmlDocument to allow for that might have complex backward compatibility consequences because changing the way the _links array is done there means that third party code using setHeadData or mergeHeadData or getHeadData (or even directly using the _links attribute) would need to adapt to the change if they get/set the "links".

I believe my solution would be a nice improvement in the short term as canonical tags are more important than self referencing hreflang tags for SEO.
And in the long term (Joomla 6 ?) a better solution which would break the backward compatibility of HtmlDocument would be even better.
That is unless someone has a better insight of the situation and/or a better solution to propose ?

avatar MacJoom
MacJoom - comment - 4 May 2025

I will prepare a PR with a separate array in the document for hreflang tags, thus enabling them to be separate of other link tags e.g. having a canonical tag with the same link, will go into 6.0 probably

avatar hikashop-nicolas
hikashop-nicolas - comment - 4 May 2025

That's indeed a great long term solution.

avatar QuyTon QuyTon - change - 5 May 2025
Status New Closed
Closed_Date 0000-00-00 00:00:00 2025-05-05 12:36:00
Closed_By QuyTon
avatar QuyTon QuyTon - close - 5 May 2025
avatar QuyTon
QuyTon - comment - 5 May 2025

Please test #45428. Thanks.

Add a Comment

Login with GitHub to post a comment