Symptom
app/api/sitemap/[lang]/route.ts emits malformed URLs and incorrect hreflang alternates for any locale that has Polylang-translated pages (currently affects all non-English).
For an Italian translated page like governance-2/governanza-del-progetto:
<loc> becomes https://catholicdigitalcommons.org/it/it/governance-2/governanza-del-progetto (doubled locale).
- The
<xhtml:link rel="alternate" hreflang="en" ...> is built from the same Italian-prefixed URI, so the English alternate also points to a non-existent IT URL.
Root cause
In app/api/sitemap/[lang]/route.ts:
function buildUrl(locale: string, path: string): string {
const prefix = localePrefix(locale)
// ...
return `${baseUrl}${prefix}${cleanPath}`
}
for (const page of pages) {
const uri = page.uri === '/' ? '/' : page.uri
// ...
entries.push(urlEntry(buildUrl(lang, uri), ..., uri))
}
page.uri from getAllPages(lang) already includes the Polylang language prefix (/it/...) in directory mode. buildUrl then prepends the prefix again. And buildAlternateLinks(uri) reuses that locale-specific URI for every hreflang, so English/Spanish/etc. alternates all point at the IT URL.
Suggested fix
Fetch and use slug (or a parent-slug chain) from WP instead of uri — same fix shape as #53. Then buildUrl(lang, '/governance-2/governanza-del-progetto') produces the right result. For hreflang alternates, you need the per-locale path (each language has its own translated slug), so either:
- query
pages once per locale and build a translation map keyed by canonical post ID, or
- include
translations { language { slug } slug } in the GraphQL query so a single fetch per locale carries all hreflang variants.
Notes
GET_ALL_PAGES in lib/wordpress/queries.ts:418 returns slug and uri; only slug is needed once this is fixed.
- This affects every non-English sitemap and degrades multilingual SEO. Worth fixing before more languages are added.
Related
Same page.uri misuse as #53.
Symptom
app/api/sitemap/[lang]/route.tsemits malformed URLs and incorrect hreflang alternates for any locale that has Polylang-translated pages (currently affects all non-English).For an Italian translated page like
governance-2/governanza-del-progetto:<loc>becomeshttps://catholicdigitalcommons.org/it/it/governance-2/governanza-del-progetto(doubled locale).<xhtml:link rel="alternate" hreflang="en" ...>is built from the same Italian-prefixed URI, so the English alternate also points to a non-existent IT URL.Root cause
In
app/api/sitemap/[lang]/route.ts:page.urifromgetAllPages(lang)already includes the Polylang language prefix (/it/...) in directory mode.buildUrlthen prepends the prefix again. AndbuildAlternateLinks(uri)reuses that locale-specific URI for every hreflang, so English/Spanish/etc. alternates all point at the IT URL.Suggested fix
Fetch and use
slug(or a parent-slug chain) from WP instead ofuri— same fix shape as #53. ThenbuildUrl(lang, '/governance-2/governanza-del-progetto')produces the right result. For hreflang alternates, you need the per-locale path (each language has its own translated slug), so either:pagesonce per locale and build a translation map keyed by canonical post ID, ortranslations { language { slug } slug }in the GraphQL query so a single fetch per locale carries all hreflang variants.Notes
GET_ALL_PAGESinlib/wordpress/queries.ts:418returnssluganduri; onlyslugis needed once this is fixed.Related
Same
page.urimisuse as #53.