Every language has its own address
2026.10.14-language-pathsA translation used to be the page address plus ?locale=es. Search engines may ignore a query parameter, a CDN may drop it, and you cannot point a search console at it as "the Spanish section". Now every language has its own path, right after the space's address:
numestri.com/docs/webhooks the original
numestri.com/docs/es/webhooks SpanishThe same applies on every address a space has (a path of your own domain, a site, /p/<org>/<space>), on every reader (docs, blog, forum, legal and the rest), and before a version: /docs/es/v2/<page>. The original never has a code. See Language addresses.
Changed
?locale=esanswers301with the path form. So does?lang=eswhen Spanish is a declared content language. Every other parameter is kept, so existing links keep working.Only a declared language is a path segment. A page called
eson a space with no Spanish keeps its address. When a language you add shares a name with a page, the language wins and the page is at/<code>?locale=default.The interface follows the address.
/docs/es/…shows its interface in Spanish too, when Spanish is an interface language.Links stay in the language. Navigation, breadcrumbs, previous/next, cards, search results, the front-door redirect and your redirect rules all keep the reader in the language they are reading. The
/docs?locale=esfront-door redirect no longer drops the query (NUM-42).Search engines see one address per language. Canonicals,
hreflang(withx-default),og:locale/og:locale:alternate,<html lang>and JSON-LDinLanguageall name the path form. The space'ssitemap.xmllists every published translation, each with<xhtml:link rel="alternate" hreflang>for the others.A fallback page is canonical to the original and no longer
noindex. This is the page served for a language with no translation whenlocaleFallback: "source"is set. It stays out ofhreflangand the sitemap.Publishing a translation purges its path address on the edge, as well as the
?locale=form.
Added
theme.i18n.urlStyle:"path"(the default) or"query", on a space or on its site. Use"query"to keep the?locale=form.localesandlocaleUrlStyleonGET /public/orgs/{orgId}/spaces/{spaceId}/seo: the declared language codes, each one a path segment, and how the space addresses them.