'Adding hreflang tags automatically in WordPress subdirectory multisite
We have a WordPress MU subdirectory network setup:
- www.example.com - main website, USA, global
- www.example.com/uk/ - to display for UK visitors
- www.example.com/au/ - to display for Australian visitors.
We want to add hreflang tags for each webpage, and exclude the locations
custom post type.
From this question, I've adjusted the code in the child theme's
functions.php
to:
function add_hreflang_attribute() {
$site_url = network_site_url(); // base URL
$alt_langs = array( '', 'au', 'uk' ); // two-letter language code
$page_path = substr(get_permalink(), strlen(home_url('/'))); // path of page after base URL
if (!( is_singular( 'locations' ) ) ) {
// loop through the alternative languages, and get the appropriate hreflang tag for each that exists
foreach ($alt_langs as $lang) {
$updated_url_lang_path = $site_url . $lang . '/' . $page_path;
$url_headers = @get_headers($updated_url_lang_path);
if($url_headers && strpos( $url_headers[0], '200')) {
if ($lang == 'uk') {
echo '<link rel="alternate" href="' . $updated_url_lang_path . '" hreflang="en-gb" />'. PHP_EOL;
} elseif ($lang == '') {
}
else {
echo '<link rel="alternate" href="' . $updated_url_lang_path . '" hreflang="en-' . $lang . '" />'. PHP_EOL;
}
}
}
// set primary as x-default
echo '<link rel="alternate" href="' . $site_url . $page_path . '" hreflang="x-default" />';
}
}
This code works on the main website's home page & example page: www.example.com/features/
;
<link rel="alternate" href="https://www.example.com/au/features/" hreflang="en-au" />
<link rel="alternate" href="https://www.example.com/uk/features/" hreflang="en-gb" />
<link rel="alternate" href="https://www.example.com/features/" hreflang="x-default" />
and it works for the:
- AU site's home page,
- the AU site's features page:
https://www.example.com/au/features/
,
but on www.example.com/uk/
it only produces:
<link rel="alternate" href="https://www.example.com/au/" hreflang="en-au" />
<link rel="alternate" href="https://www.example.com/" hreflang="x-default" />
It is missing:
<link rel="alternate" href="https://www.example.com/uk/" hreflang="en-gb" />
The features page is a simple WordPress page.
Help appreciated.
EDIT
If I add if ($lang == 'uk') {print_r(get_headers($updated_url_lang_path));}
, I see:
Array
(
[0] => HTTP/1.1 200 OK
[1] => Server: nginx
[2] => Date: Wed, 11 May 2022 22:08:04 GMT
[3] => Content-Type: text/html; charset=UTF-8
[4] => Content-Length: 88422
[5] => Connection: close
[6] => Vary: Accept-Encoding
[7] => Vary: Accept-Encoding
[8] => Accept-CH: Sec-CH-UA-Mobile
[9] => Link: <https://www.example.com/uk/wp-json/>; rel="https://api.w.org/"
[10] => Link: <https://www.example.com/uk/wp-json/wp/v2/pages/10>; rel="alternate"; type="application/json"
[11] => Link: <https://www.example.com/uk/>; rel=shortlink
[12] => X-Powered-By: WP Engine
[13] => X-Cacheable: SHORT
[14] => Vary: Accept-Encoding,Cookie
[15] => Cache-Control: max-age=600, must-revalidate
[16] => X-Cache: HIT: 8
[17] => X-Cache-Group: normal
[18] => Accept-Ranges: bytes
[19] => X-Orig-Cache-Control: no-cache
)
and the following is added properly:
<link rel="alternate" href="https://www.example.com/uk/" hreflang="en-gb" />
However, I only see this while logged into WordPress.
In an incognito window, at https://www.example.com/uk/
I see (only):
<link rel="alternate" href="https://www.example.com/" hreflang="x-default" />
Solution 1:[1]
I altered the code to:
function mm_add_hreflang_attribute() {
if (!( is_singular( 'locations' ) ) ) {
$sites = array(
array('', 'x-default'),
array('en-gb/', 'en-gb'),
array('en-au/', 'en-au'),
);
if ( is_post_type_archive('locations') ) {
foreach ( $sites as $site ) {
$site_url = network_site_url();
$page_path = 'locations/';
$geo_url = $site[0];
$hreflang = $site[1];
$url = $site_url . $geo_url . $page_path;
echo '<link rel="alternate" href="' . $url . '" hreflang="' . $hreflang . '" />'. PHP_EOL;
}
} else {
foreach ( $sites as $site ) {
$site_url = network_site_url();
$page_path = substr(get_permalink(), strlen(home_url('/')));
$geo_url = $site[0];
$hreflang = $site[1];
$url = $site_url . $geo_url . $page_path;
echo '<link rel="alternate" href="' . $url . '" hreflang="' . $hreflang . '" />'. PHP_EOL;
}
}
}
}
add_action('wp_head', 'mm_add_hreflang_attribute', 1);
which works well.
Solution 2:[2]
Hey Steve, Use this code, It will work well!!!
function mm_add_hreflang_attribute() {
if (!( is_singular( 'locations' ) ) ) {
$sites = array(
array('', 'x-default'),
array('en-gb/', 'en-gb'),
array('en-au/', 'en-au'),
);
if ( is_post_type_archive('locations') ) {
foreach ( $sites as $site ) {
$site_url = network_site_url();
$page_path = 'locations/';
$geo_url = $site[0];
$hreflang = $site[1];
$url = $site_url . $geo_url . $page_path;
echo '<link rel="alternate" href="' . $url . '" hreflang="' . $hreflang . '" />'. PHP_EOL;
}
}
else
{
foreach ( $sites as $site ) {
$site_url = network_site_url();
$page_path = substr(get_permalink(), strlen(home_url('/')));
$geo_url = $site[0];
$hreflang = $site[1];
$url = $site_url . $geo_url . $page_path;
echo '<link rel="alternate" href="' . $url . '" hreflang="' . $hreflang . '" />'. PHP_EOL;
}
}
}
}
add_action('wp_head', 'mm_add_hreflang_attribute', 1);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Steve |
Solution 2 | Juned Shekh |