Resolved

Reported for: WPML Multilingual CMS 3.8.3

Resolved in: 3.9.0

Symptoms

When a language has a two-letter code on the tag and a longer code in the default locale, the latter is used to render the hreflang tags.

Workaround

A fix will be provided with the next major version of WPML, where the word “tag” will be replaced with “hreflang” to avoid confusion and the correct logic will be used.

Meanwhile, you can use the following steps to solve this issue:

  1. Make a backup of your site.
  2. Find and edit the class-wpml-seo-headlangs.php file in the ../sitepress-multilingual-cms/classes/seo/ folder, where sitepress-multilingual-cms is the directory where WPML is installed.
  3. At around line 139, you should find the following code:
    private function get_hreflang_code( $lang ) {
    	$tag           = $lang['tag'];
    	$locale        = $lang['default_locale'];
    	$hreflang_code = $this->get_best_code( array( $tag, $locale ) );
    	$hreflang_code = str_replace( '_', '-', $hreflang_code );
    	$hreflang_code = strtolower( $hreflang_code );
    
    	if ( $this->is_valid_hreflang_code( $hreflang_code ) ) {
    		return trim( $hreflang_code );
    	}
    
    	return '';
    }
  4. Replace it with this code:
    private function get_hreflang_code( $lang ) {
    	$ordered_keys = array( 'tag', 'default_locale' );
    
    	$hreflang_code = '';
    	foreach ( $ordered_keys as $key ) {
    		if ( array_key_exists( $key, $lang ) && trim( $lang[ $key ] ) ) {
    			$hreflang_code = $lang[ $key ];
    			break;
    		}
    	}
    
    	$hreflang_code = strtolower( str_replace( '_', '-', $hreflang_code ) );
    
    	if ( $this->is_valid_hreflang_code( $hreflang_code ) ) {
    		return trim( $hreflang_code );
    	}
    
    	return '';
    }