From 08fd4ea85dcff31b429d8fd20dc30b769391e117 Mon Sep 17 00:00:00 2001 From: Meindert Date: Thu, 3 Sep 2026 16:06:48 +0200 Subject: [PATCH] Keep the sitemap a localized URL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The winter.sitemap.addItem listener rewrites to the alternate for the default locale and clones a for each of the others. When the default locale is not among alternateLinks the rewrite never happens and the element keeps the untranslated URL it was built with — a URL that belongs to no locale and, on an install that prefixes locales, redirects. The sitemap then advertises a redirect instead of a canonical URL. A listener on pages.menuitem.resolveItem may legitimately narrow alternateLinks: serving a subset of the locales per host, for instance. Falling back to the first alternate keeps every a real localized URL. Unfiltered alternateLinks always contain the default locale, so nothing changes for the usual case. --- Plugin.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Plugin.php b/Plugin.php index ff17680..3f5fdaf 100644 --- a/Plugin.php +++ b/Plugin.php @@ -441,8 +441,15 @@ function (DefinitionItem $item, array $itemInfo, Definition $definition, DOMDocu $linkElement->setAttribute('href', $altUrl); $urlElement->appendChild($linkElement); } + // A listener on pages.menuitem.resolveItem may narrow + // alternateLinks. Without the default locale among them the + // would keep the untranslated URL, which redirects. + $primaryLocale = isset($itemInfo['alternateLinks'][$defaultLocale->code]) + ? $defaultLocale->code + : array_key_first($itemInfo['alternateLinks']); + foreach ($itemInfo['alternateLinks'] as $locale => $altUrl) { - if ($locale === $defaultLocale->code) { + if ($locale === $primaryLocale) { $loc = $urlElement->getElementsByTagName('loc')->item(0); $loc->nodeValue = $altUrl; continue;