Issue with Sanity GROQ fetch returning string data with zero width spaces.

2 replies
Last updated: May 16, 2024
Hello,Does anyone know why all of a sudden Sanity GROQ fetch is returning string data with a lot of zero width spaces?
AI Update

This is likely happening because you have Stega encoding enabled in your Sanity client! Stega is a feature that invisibly embeds metadata into your content strings using zero-width UTF-8 characters to power Visual Editing features.

Why This Happens

When Stega encoding is active (usually in preview/draft mode), Sanity automatically appends invisible characters to strings in your fetched data. These characters contain Content Source Map metadata that enables click-to-edit overlays in the Presentation tool. To users, the text looks normal, but the zero-width spaces are actually there in the string data.

How to Fix It

Option 1: Disable Stega (if you don't need Visual Editing)

If you're not using Visual Editing features, you can disable Stega in your client configuration:

import { createClient } from '@sanity/client'

export const client = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  apiVersion: '2024-01-01',
  useCdn: true,
  stega: { enabled: false } // Disable stega encoding
})

Or if you're using @sanity/client/stega, switch to the regular client import:

// Instead of this:
import { createClient } from '@sanity/client/stega'

// Use this:
import { createClient } from '@sanity/client'

Option 2: Clean Stega Characters (if you need them for Visual Editing)

If you need Stega for preview mode but it's interfering with your business logic, use the vercelStegaSplit or vercelStegaCleanAll utilities from @vercel/stega:

import { vercelStegaSplit } from '@vercel/stega'

export function MyComponent({ text }) {
  const { cleaned, encoded } = vercelStegaSplit(text)
  
  // Use 'cleaned' for business logic
  if (cleaned === 'some-value') {
    // Your logic here
  }
  
  // Render both to preserve Visual Editing
  return (
    <div>
      {cleaned}
      <span style={{ display: 'none' }}>{encoded}</span>
    </div>
  )
}

For cleaning entire objects:

import { vercelStegaCleanAll } from '@vercel/stega'

const cleanedData = vercelStegaCleanAll(yourData)

Common Scenarios Where This Matters

As noted in the troubleshooting documentation, Stega characters can cause issues with:

  • String equality checks (if (value === 'expected') will fail)
  • Select option values in forms
  • CSS with negative letter-spacing
  • Components like <ReactWrapBalancer>

The key is to clean the strings before using them in business logic while preserving the encoded versions for Visual Editing to work properly.

This is STEGA. Its the path to where the the data lives in sanity. This is used for the presentation edit/providing links back to the studio.
https://www.sanity.io/docs/stega#fad3406bd530 You can remove it with

import {vercelStegaCleanAll} from "@sanity/client/stega"

function showDocument(document: SanityDocument, currentMarket: string) {
  return vercelStegaCleanAll(document.market) === currentMarket
}
Aha so this happened on live editing preview mode. Makes sense. Thank you for the guide.

Sanity – Build the way you think, not the way your CMS thinks

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.

Was this answer helpful?