
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI totally understand your challenge! You want cleaner URLs with the language code as a directory (like /fr/page-name) instead of appending it to the slug (like /page-name-fr). This is definitely achievable with Sanity, and it's actually a common pattern for multilingual sites.
The key is understanding that Sanity stores your content, but your frontend application (like Next.js, Nuxt, or whatever you're using) determines the actual URL structure. Here's how to approach this:
When using document-level internationalization (which sounds like what you're doing), each language version is a separate document. You'll want to:
Use the same slug across translations - Instead of naming your French page "Page Name Fr" with slug page-name-fr, just use page-name for both the English and French versions. Store the language as a separate field (like language: 'fr' or language: 'en').
Structure your frontend routes - Set up your routing to include the language code in the path. For example, in Next.js, you'd create a file structure like pages/[lang]/[slug].js or use the built-in i18n routing.
Query by language and slug - When someone visits /fr/page-name, your frontend extracts both the language (fr) and slug (page-name), then queries Sanity for the document matching both criteria:
*[_type == "page" && slug.current == $slug && language == $lang][0]Your document structure would look like:
{ title: "Page Name", slug: "page-name", language: "en" }{ title: "Nom de la page", slug: "page-name", language: "fr" }Notice both use the same slug, but different language codes. Your frontend routing handles the /fr/ or /en/ prefix, while Sanity just stores the base slug.
This approach gives you the clean URL structure you want (domain.com/fr/page-name) while keeping your content organized in Sanity. The @sanity/document-internationalization plugin can help manage these relationships and make it easier for editors to navigate between translations in the Studio.
This is similar to how WordPress plugins like Polylang and WPML handle the "same slug across languages" feature - the CMS allows duplicate slugs differentiated by language, and the frontend routing adds the language directory prefix. For more details on document-level localization, check out Sanity's localization documentation!
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store