How does Sanity's GraphQL endpoint return Portable Text as parsed JSON?
The Sanity GraphQL endpoint returns Portable Text as raw JSON through a special field naming convention. When you have a Portable Text field in your schema, the GraphQL API automatically generates a <fieldName>Raw field that contains the Portable Text content as a JSON scalar type.
How it works
For example, if you have a field called body that contains Portable Text, the GraphQL schema will expose it as bodyRaw. This field returns the Portable Text as parsed JSON (not a JSON string), which means you can directly use it in your frontend without needing JSON.parse().
Here's what this looks like in a query:
{
allPost {
title
bodyRaw
}
}The bodyRaw field will return the Portable Text structure as a proper JSON object, ready to be passed to your BlockContent component or any Portable Text renderer.
Why you might be getting a string
If you're receiving the Portable Text as a JSON string (requiring JSON.parse()), this is likely due to how your GraphQL client or server is handling the response. The issue might be:
- Your GraphQL client serialization: Some GraphQL clients might be stringifying the response
- dotnet-graphql configuration: The .NET GraphQL library might need configuration to properly handle JSON scalar types
- Custom scalar handling: You may need to define how the JSON scalar type should be handled in your GraphQL implementation
For .NET/GraphQL.NET specifically
In GraphQL.NET (which is commonly used with dotnet-graphql), you'll want to ensure you have proper JSON scalar support. GraphQL.NET provides a JsonGraphType that can handle arbitrary JSON data. The Sanity GraphQL API uses a JSON scalar for the *Raw fields, so your .NET client needs to understand how to deserialize this type.
If you're using Hot Chocolate (another popular .NET GraphQL library), it has built-in JsonType support that should handle this automatically.
The key issue is that the JSON scalar type in GraphQL is not a standard scalar like String or Int—it's a custom scalar that represents arbitrary JSON. Your .NET GraphQL client needs to be configured to treat this as an object/dictionary rather than a string.
Alternative: Consider GROQ
While Sanity supports GraphQL, I'd recommend considering GROQ (Sanity's native query language) instead. GROQ handles Portable Text more naturally and gives you more flexibility in how you query and transform your content. It also has type generation support, making it type-safe like GraphQL.
If you do need to stick with GraphQL, the key is ensuring your .NET GraphQL client properly handles JSON scalar types without stringifying them. You might need to configure a custom scalar type handler in your GraphQL client library.
Show original thread12 replies
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.