
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI understand you want to implement a Portable Text editor directly on your client-side application, not just in Sanity Studio. You're right that much of the documentation focuses on rendering Portable Text, but there are options for creating editing experiences on the client side.
The Portable Text Editor is indeed a standalone React-based editor that can be used outside of Sanity Studio. However, it's important to understand that this isn't a drop-in component - it requires significant integration work. You'll need to:
This is a lower-level library that gives you the editing engine, but you're responsible for building the complete editing experience around it.
Given the complexity of implementing the Portable Text Editor from scratch, here are more practical approaches:
Use a rich text editor you're comfortable with (like TipTap, Quill, or Slate) and convert the output to Portable Text format. The @sanity/block-tools package can help with this:
import {htmlToBlocks} from '@sanity/block-tools'
import {Schema} from '@sanity/schema'
// Define a simple schema
const defaultSchema = Schema.compile({
name: 'myBlog',
types: [
{
type: 'object',
name: 'blogPost',
fields: [
{
title: 'Body',
name: 'body',
type: 'array',
of: [{type: 'block'}]
}
]
}
]
})
const blockContentType = defaultSchema
.get('blogPost')
.fields.find(field => field.name === 'body').type
const blocks = htmlToBlocks('<p>Your HTML content</p>', blockContentType)The @sanity/block-tools package handles basic rich text formatting like headings, paragraphs, and lists automatically, and you can define custom deserialization rules for more complex HTML structures.
For simpler use cases, you might create a custom editing interface using standard form inputs and structure the data as Portable Text yourself. Then use @sanity/client to write it back:
import {createClient} from '@sanity/client'
const client = createClient({
projectId: 'your-project-id',
dataset: 'your-dataset',
token: 'your-write-token', // Keep this secure!
apiVersion: '2024-01-01',
useCdn: false
})
// Write Portable Text data
client
.patch('document-id')
.set({
body: [
{
_type: 'block',
children: [{_type: 'span', text: 'Your content here'}]
}
]
})
.commit()If you need full editing capabilities, consider embedding Sanity Studio itself into your application using an iframe or as a React component. This gives you the complete, battle-tested editing experience without reimplementing it.
For most use cases, I'd recommend using a familiar rich text editor (like TipTap) with @sanity/block-tools for conversion. This gives you:
Only invest in implementing the Portable Text Editor directly if you need deep customization of the editing experience and have the development resources to build and maintain the surrounding infrastructure.
The key is to remember that whatever approach you choose, as long as you output valid Portable Text JSON, it will work seamlessly with Sanity's rendering libraries and ecosystem.
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