Problem
URLs in the site's static navigation never use translated slugs. Example: in the Header dropdown under Governance, "Criteri di valutazione" links to:
https://catholicdigitalcommons.org/it/governance/project-governance/project-vetting-criteria
The page renders Italian content (because WPGraphQL+Polylang resolves the English URI to the Italian translation server-side), but the URL itself stays in English.
The Italian slugs do exist in WordPress — Polylang auto-generated them from translated post titles (e.g. governanza-del-progetto). They're simply never consumed by the Next.js front-end.
Why
Two missing pieces:
src/i18n/routing.ts:7 defines no pathnames map. Without one, createNavigation(routing) (src/i18n/navigation.ts) only prepends the locale; it never translates path segments.
components/Header.tsx (and components/Footer.tsx) hardcode English paths (/governance/project-governance/project-vetting-criteria, etc.). With no pathnames map, those strings pass through verbatim.
The catch-all route app/[lang]/[[...slug]]/page.tsx:27 then does getPage(slug.join('/'), lang) against a WPGraphQL query (page(id: $slug, idType: URI).translation(language: $language)) that resolves English URIs to translations — which is why the page loads at all, but explains why nobody noticed the URL stayed English.
Suggested implementation
- Generate a
pathnames map at build time from getAllPages(locale) for each locale. Key: canonical English URI; values: per-locale translated paths. Keep as a generated file (e.g. src/i18n/pathnames.generated.ts) regenerated on deploy. (The getAllPages query already returns slug per locale; a small extension to include parent-slug chains is enough to compose translated paths.)
- Add
pathnames to defineRouting in src/i18n/routing.ts.
- Update the catch-all route to look up pages by language-aware URI. Two options:
- switch
GET_PAGE_BY_SLUG to use nodeByUri(uri: $uri) and pass the locale-prefixed URI, or
- reverse-map the incoming localized slug → canonical English slug before calling
getPage (using the same pathnames map).
- Header/Footer remain unchanged — they keep their canonical English
hrefs; next-intl substitutes the localized path automatically once pathnames is configured.
Dependencies
Depends on #53 and the sitemap fix being resolved first, since they share the WP query layer (GET_ALL_PAGES, GET_CHILD_PAGES).
Open questions
- Italian governance root currently has slug
governance-2 (WP collision suffix because English took governance). Worth renaming to governanza in WP admin before the pathnames map gets baked in, so users don't have to re-bookmark.
- Whether to drive the Header from a Polylang-managed nav menu in WP (more work, more maintainable as pages get renamed) vs. keeping it hardcoded with a generated
pathnames map.
Problem
URLs in the site's static navigation never use translated slugs. Example: in the Header dropdown under Governance, "Criteri di valutazione" links to:
https://catholicdigitalcommons.org/it/governance/project-governance/project-vetting-criteriaThe page renders Italian content (because WPGraphQL+Polylang resolves the English URI to the Italian translation server-side), but the URL itself stays in English.
The Italian slugs do exist in WordPress — Polylang auto-generated them from translated post titles (e.g.
governanza-del-progetto). They're simply never consumed by the Next.js front-end.Why
Two missing pieces:
src/i18n/routing.ts:7defines nopathnamesmap. Without one,createNavigation(routing)(src/i18n/navigation.ts) only prepends the locale; it never translates path segments.components/Header.tsx(andcomponents/Footer.tsx) hardcode English paths (/governance/project-governance/project-vetting-criteria, etc.). With nopathnamesmap, those strings pass through verbatim.The catch-all route
app/[lang]/[[...slug]]/page.tsx:27then doesgetPage(slug.join('/'), lang)against a WPGraphQL query (page(id: $slug, idType: URI).translation(language: $language)) that resolves English URIs to translations — which is why the page loads at all, but explains why nobody noticed the URL stayed English.Suggested implementation
pathnamesmap at build time fromgetAllPages(locale)for each locale. Key: canonical English URI; values: per-locale translated paths. Keep as a generated file (e.g.src/i18n/pathnames.generated.ts) regenerated on deploy. (ThegetAllPagesquery already returnsslugper locale; a small extension to include parent-slug chains is enough to compose translated paths.)pathnamestodefineRoutinginsrc/i18n/routing.ts.GET_PAGE_BY_SLUGto usenodeByUri(uri: $uri)and pass the locale-prefixed URI, orgetPage(using the same pathnames map).hrefs; next-intl substitutes the localized path automatically oncepathnamesis configured.Dependencies
Depends on #53 and the sitemap fix being resolved first, since they share the WP query layer (
GET_ALL_PAGES,GET_CHILD_PAGES).Open questions
governance-2(WP collision suffix because English tookgovernance). Worth renaming togovernanzain WP admin before the pathnames map gets baked in, so users don't have to re-bookmark.pathnamesmap.