Skip to content Skip to sidebar

This thread is resolved. Here is a description of the problem and solution.

Problem:
The client is trying to ensure that only one page is referenced for each language in hreflang annotations on their homepage. Additionally, the translated (en-ca) homepage is not appearing in the page-sitemap. Unexpectedly, there is an additional 301 redirect hreflang tag to the full en-ca homepage URL, and the en-ca homepage is not visible in the page-sitemap.

Solution:
To address the hreflang annotations, we recommend modifying the code in the WPML SEO plugin. Open the file at

...\wp-content\plugins\wp-seo-multilingual\classes\Shared\Sitemap\BaseAlternateLangHooks.php

. On line 61, replace:

$link[ self::KEY ][ $lang ] = apply_filters( 'wpml_permalink', $link['loc'], $lang );

with:

$link[ self::KEY ][ $lang ] = apply_filters( 'wpml_permalink', $link['loc'], $lang, true );

Apply the same change on line 89.

For the sitemap issue with Rank Math, navigate to "Rank Math > Sitemaps settings" and alter the "Links per sitemap" number then save. This action will rebuild the sitemaps. You can revert to the original number after this change.

If these steps do not resolve your issue or if the solution becomes outdated, we highly recommend checking related known issues at https://wpml.org/known-issues/, verifying the version of the permanent fix, and confirming that you have installed the latest versions of themes and plugins. If the problem persists, please open a new support ticket.

This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

Tagged: 

This topic contains 14 replies, has 0 voices.

Last updated by Lauren 5 months, 1 week ago.

Assisted by: Lauren.

Author Posts
October 23, 2025 at 6:51 pm

francisC-12

Background of the issue:
I am trying to make the necessary edits to the hreflang annotations on the homepage so that only one page is referenced for one language. I am also trying to figure out why the translated (en-ca) homepage isn't showing in the page-sitemap. Link to a page where the issue can be seen: hidden link

Symptoms:
I expected to see only the fr-ca, en-ca, and the x-default hreflangs on the main language homepage. I also expect to see the translated homepage in the sitemap, but for some reason, it's not there. Instead, I got an additional 301 redirect hreflang tag to the full en-ca homepage URL. I see hidden link for en-ca on top of hidden link. It can't be seen in the source code, but it's flagged by an SEO audit. I'm also not sure why the en-ca homepage isn't showing in the page-sitemap at all.

Questions:
How can I ensure only one page is referenced for each language in hreflang annotations?
Why isn't the translated en-ca homepage showing in the page-sitemap?

October 28, 2025 at 8:04 pm #17527470

Lauren

I've been trying to reproduce the issue on the staging site, but I ran into an issue with some tests and need FTP access to resolve the code snippet I was testing on the staging site. Can you either share FTP access or remove the snippet from the Twenty Twenty Five functions.php? It will be the last bit of code in that file. Let me know once that's done, and it will be ideal if I can have staging site FTP as I continue testing.

October 29, 2025 at 3:23 pm #17530126

francisC-12

I corrected the fatal error. You can resume work.

Also I can send SFTP access but I wanna make sure this is private before doing so. How should I proceed?

October 29, 2025 at 4:17 pm #17530298

Lauren

Thanks so much. The next field is marked as private and has private fields to securely share the credentials. Make sure to only put the senstive data in the private fields and not the general reply section. Thanks!

October 31, 2025 at 9:43 pm #17536850

francisC-12

I was working on a new homepage which I just published on the main website. It solved the sitemap issue. I can see the translated homepage in the page sitemap now.

However, I still have the issue with the hreflang links. In the source code, I do see the 3 expected hreflang tags, which are fr-ca, en-ca and x-default. However, when I do a SEO audit of the website, 4 hreflang tags are detected on the homepage in both languages. It seems that the full url of the homepage (domain.com/en-ca/home/) is also being detected instead of just domain.com/en-ca/, resulting in two pages/links for the same language en-ca.

Any know reasons why this is happening?

November 4, 2025 at 10:38 pm #17547791

francisC-12

Hello,

I still need help with this. On the source code we do see the 3 correct hreflangs tags.

However, on the page sitemap (hidden link) we see the wrong url when inspecting with the chrome devtools sources tab. Here's what we get :
/
<url>
<loc>hidden link;
<xhtml:link rel="alternate" hreflang="fr-ca" href="hidden link" />
<xhtml:link rel="alternate" hreflang="en-ca" href="hidden link" />
<xhtml:link rel="alternate" hreflang="x-default" href="hidden link" />
</url>
<url>
<loc>hidden link;
<xhtml:link rel="alternate" hreflang="fr-ca" href="hidden link" />
<xhtml:link rel="alternate" hreflang="en-ca" href="hidden link" />
<xhtml:link rel="alternate" hreflang="x-default" href="hidden link" />
</url>
/

We also have 4 hreflangs detected when doing a SEO audit of the website, as stated before.

I need help to ensure that the correct language link is showing for the en-ca homepage, which is without the /home/ at the end.

Thanks.

November 7, 2025 at 1:36 am #17555839

Lauren

Please try inserting the additional code into your theme's functions.php:

// Fix Rank Math sitemap hreflang for translated homepages (WPML).
if ( defined('RANK_MATH_VERSION') ) {

  /**
   * Ensure the EN-CA alternate for the FRONT PAGE uses /en-ca/ (not /en-ca/home/).
   * Works for both the FR entry and the EN entry in page-sitemap.xml.
   */
  add_filter('rank_math/sitemap/alternate_urls', function($alternates, $post){
      if ( ! ($post instanceof WP_Post) || $post->post_type !== 'page' ) return $alternates;

      // Default (FR) front page ID and its EN-CA translation ID
      $fr_front = (int) get_option('page_on_front');
      if ( ! $fr_front ) return $alternates;

      $en_front = $fr_front;
      if ( function_exists('apply_filters') ) {
          $maybe = apply_filters('wpml_object_id', $fr_front, 'page', true, 'en-ca');
          if ( $maybe ) $en_front = (int) $maybe;
      }

      // Only adjust when the sitemap entry is the FR or EN front page.
      if ( (int) $post->ID !== $fr_front && (int) $post->ID !== $en_front ) return $alternates;

      // Build the correct EN-CA home URL (directory, not the 'home' slug).
      $en_home = function_exists('apply_filters')
          ? apply_filters('wpml_home_url', home_url('/'), 'en-ca')
          : home_url('/en-ca/');

      // Replace the EN-CA alternate URL if present.
      foreach ( $alternates as &$alt ) {
          if ( ! empty($alt['hreflang']) && strtolower($alt['hreflang']) === 'en-ca' ) {
              $alt['href'] = rtrim($en_home, '/') . '/';
          }
      }
      unset($alt);

      return $alternates;
  }, 20, 2);

  /**
   * Also make sure the EN-CA FRONT PAGE <loc> itself is /en-ca/ (not /en-ca/home/).
   */
  add_filter('rank_math/sitemap/entry', function($entry, $type, $object){
      if ( $type !== 'page' || ! ($object instanceof WP_Post) ) return $entry;

      $fr_front = (int) get_option('page_on_front');
      if ( ! $fr_front ) return $entry;

      $en_front = $fr_front;
      if ( function_exists('apply_filters') ) {
          $maybe = apply_filters('wpml_object_id', $fr_front, 'page', true, 'en-ca');
          if ( $maybe ) $en_front = (int) $maybe;
      }

      // If this entry is the EN-CA front page, normalize its <loc> to /en-ca/
      if ( (int) $object->ID === $en_front ) {
          $en_home = function_exists('apply_filters')
              ? apply_filters('wpml_home_url', home_url('/'), 'en-ca')
              : home_url('/en-ca/');
          $entry['loc'] = rtrim($en_home, '/') . '/';
      }

      // If this entry is the FR front page, keep <loc> as-is (root), but alternates will be fixed by the other filter.
      return $entry;
  }, 20, 3);
}

Then hard-refresh the dynamic sitemap

Open each with ?nocache=1 to bypass any page cache:
hidden link
hidden link

Please let me know if this changes anything.

November 12, 2025 at 9:51 pm #17572813

francisC-12

Thank you for the code snippet you provided. Unfortunately, it didn't solve the issue.

I added the code to my child theme's functions.php, then emptied all cache, saved the site permalinks and refreshed the sitemaps, then used the nocache url to view the page-sitemap. Result: I'm still seeing the /en-ca/home/ url in the sources on chrome devtools.

Any other solution I can try?

November 13, 2025 at 9:46 pm #17576812

Lauren

I have escalated this issue to our compatibiltiy team to look further into why RankMath is registering the translated homepage as /home/ instead of just the language code. I'll update here just as soon as I have more information.

November 14, 2025 at 8:55 pm #17580259

Lauren

I'm not seeing the /en-ca/home/ page on the dev site hidden link

Can you please share a screenshot of where you are seeing it in the devtools?

November 17, 2025 at 3:36 pm #17584922

francisC-12

I think you don’t see it because the translated homepage (/en-ca/) isn’t included in the sitemap on the staging site. Please refer to my message sent on October 31, 2025, at 9:43 PM. At that time, I mentioned:

“I was working on a new homepage that I just published on the main website. It solved the sitemap issue — I can now see the translated homepage in the page sitemap.”

Indeed, I replaced the homepage with a new one, which resolved the issue of the homepage not appearing in the sitemap.

Now, the remaining issue is that a fourth hreflang (/en-ca/home/) is still being detected during an SEO audit with Ahrefs. I spoke with their support, and they confirmed that the problem comes from the sitemap itself. Specifically, the /page-sitemap.xml contains this line in the source code:

<xhtml:link rel="alternate" hreflang="en-ca" href="hidden link" />

This value doesn’t appear on the actual pages, only in the sitemap, which is why the audit tool flags it as an extra hreflang apparently.

To view the incorrect value, I inspect the /page-sitemap.xml file in Chrome DevTools under the Sources tab and refresh the page. I’ve attached a screenshot showing what I see.

We need to make sure that the sitemap references /en-ca/ instead of /en-ca/home/.

Can you help?

sources-tab-hreflang-issue.png
November 18, 2025 at 4:20 pm #17588913

Lauren

Thank you for the additional information, we are able to reproduce this on a sandbox site. I have escalated this and our compatibility team is looking further into this. I will update there as soon as I have more information.

November 20, 2025 at 4:41 pm #17596676

Lauren

HEre's a workaround our 2nd tier support found. Open the ...\wp-content\plugins\wp-seo-multilingual\classes\Shared\Sitemap\BaseAlternateLangHooks.php file

Look for line 61

Replace:

$link[ self::KEY ][ $lang ] = apply_filters( 'wpml_permalink', $link['loc'], $lang );

with:

$link[ self::KEY ][ $lang ] = apply_filters( 'wpml_permalink', $link['loc'], $lang, true );

While we're here, you ca do the same on line 89

They couldn't find where to clear the sitemap with RankMath (Yoast as a helper tool add-on for that)

What they ended up was to go to "Rank Math > Sitemaps settings" and change the "Links per sitemap" number and save. It will rebuild the sitemaps with the new number of links. You can go back to your previous number after this change.

Please let us know if this resolves the issue for you.

November 24, 2025 at 2:53 pm #17605281

francisC-12

Hello, thanks for the workaround. It seems to work well.

I no longer see any xhtml:link tags in the page-sitemap, and the SEO audit now detects the correct 3 hreflang tags (fr-ca, en-ca and x-default). The /en-ca/home/ redirect issue is also resolved.

Should I expect to reapply this change after future updates? I’m assuming the code in
wp-content/plugins/wp-seo-multilingual/classes/Shared/Sitemap/BaseAlternateLangHooks.php might be overwritten again.

Thank you.

November 24, 2025 at 7:22 pm #17606076

Lauren

Excellent, I'm glad this resolved the issue. This fix will be included in a future release so you shouldn't have to worry about it overwriting or doing it again in the future (https://wpml.org/errata/wpml-seo-incorrect-urls-in-sitemap-alternate-links/).

Thanks for the update!