
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI can see you're hitting a frustrating issue where your translation query works in Studio but returns empty translations on the frontend. This is a common problem when working with document-level localization patterns, and the root cause is almost certainly related to API perspectives.
Your Sanity Studio's Vision tool and your frontend Next.js app are likely querying different "views" of your content. The API version 2025-02-19 introduced a breaking change where the default perspective switched from raw to published. This means:
raw perspective by default, which shows all documents including draftspublished, which only shows published documentsSince your path("i18n." + ^._id + ".*") pattern is looking for documents with specific ID patterns, if those translation documents aren't published (they're only drafts), they won't appear in your frontend results.
Try explicitly setting the perspective in your frontend Sanity client:
import { createClient } from '@sanity/client'
const client = createClient({
projectId: 'your-project-id',
dataset: 'your-dataset',
apiVersion: '2024-01-01', // or your current version
perspective: 'previewDrafts', // Shows published + drafts, prioritizing drafts
useCdn: false, // Disable CDN while debugging
})The previewDrafts perspective will give you both published and draft documents, prioritizing drafts when both exist. You could also try perspective: 'raw' which shows all documents.
Your translation documents (those with i18n.* IDs) might exist only as drafts. To debug this, run a simple query from your frontend:
const result = await client.fetch('*[_id match "i18n.*"]')
console.log(result)If this returns empty but works in Studio, you've confirmed it's a perspective/publication issue. Make sure your translation documents are actually published (not just saved as drafts). In Sanity, draft documents have a drafts. prefix in their _id, and they won't appear in queries using the published perspective.
Verify document visibility: Run *[_id match "i18n.*"] from your frontend with different perspectives:
perspective: 'published' (current default for newer API versions)perspective: 'previewDrafts' (published + drafts, with drafts prioritized)perspective: 'raw' (all documents)Check publication status in Studio: Go to your Studio and verify that your translation documents (the ones with i18n.* IDs) are actually published. Look for the "Publish" button - if it's available, the document is still a draft.
Disable CDN caching: Set useCdn: false temporarily to ensure you're not hitting stale cached results.
Compare Studio Vision configuration: Your Studio's Vision tool might be using a different perspective than your frontend. Check if there's a perspective selector in Vision.
Test with simpler queries first: Before running the complex translation query, make sure you can see the basic documents with *[_type == "blog"] and the translation documents with *[_id match "i18n.*"].
The approach you're using with path("i18n." + ^._id + ".*") relies on document ID pattern matching, which is sensitive to perspective and publication state. The pattern itself is solid, but it requires that the documents it's looking for are visible in the perspective you're querying with.
For immediate debugging:
// In your frontend client configuration
const client = createClient({
// ... your existing config
perspective: 'previewDrafts',
useCdn: false,
})For production: Once you've confirmed the issue, decide on your approach:
perspective: 'published' in productionperspective: 'previewDrafts' if you need to show draft translations in your frontendThe key insight here is that Studio and your frontend are querying different views of your content due to perspective differences. Studio's Vision tool often shows all documents (similar to raw perspective), while your frontend clientâespecially if using a recent API versionâdefaults to only published documents. This explains why you see translations in Studio but not in your Next.js app.
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