How to model floated images within text content in Sanity?
Welcome to Sanity! This is a great question and one that many people coming from WordPress encounter. The good news is that Sanity absolutely supports this pattern - you're not missing anything, and you're thinking about it the right way.
In Sanity, this is handled using Portable Text, which is Sanity's rich text format. Unlike WordPress's traditional HTML-based editor, Portable Text stores content as structured JSON data. The key is that you can insert custom blocks (like images) directly within your text content, and then control how they're rendered on the frontend.
The Schema Setup
In your schema, define your content field as an array that includes both text blocks and image blocks with an alignment field:
{
title: 'Body Content',
name: 'body',
type: 'array',
of: [
{
type: 'block' // Regular text paragraphs
},
{
type: 'object',
title: 'Image',
name: 'blockImage',
fields: [
{
type: 'image',
name: 'image',
options: {
hotspot: true
}
},
{
type: 'string',
name: 'alignment',
title: 'Alignment',
options: {
list: [
{ title: 'Left', value: 'left' },
{ title: 'Center', value: 'center' },
{ title: 'Right', value: 'right' }
],
layout: 'radio',
direction: 'horizontal'
}
},
{
type: 'string',
name: 'alt',
title: 'Alternative text'
}
]
}
]
}This allows your content editors to insert images directly into the text flow, just like in WordPress. The alignment field lets them specify how the image should float.
Rendering on the Frontend
When you render this content, you'll use a Portable Text renderer (like @portabletext/react for React) and define custom components for how images should display:
import { PortableText } from '@portabletext/react'
const components = {
types: {
blockImage: ({value}) => (
<img
src={urlFor(value.image).url()}
alt={value.alt}
className={`float-${value.alignment}`}
// or style={{float: value.alignment}}
/>
)
}
}
<PortableText value={content} components={components} />About Separation of Concerns
You're absolutely right to think about this! The way Sanity handles it is actually a nice middle ground: the content editor specifies the intent (this image should be positioned to the left), but your frontend code determines the implementation (the actual CSS classes, breakpoints, responsive behavior, etc.). This is different from WordPress where HTML/CSS is often directly embedded in content.
This approach gives you the best of both worlds - editors get the control they need to create the layouts they want, but you maintain full control over how those layouts actually work across different devices and contexts.
Preview Considerations
As mentioned in this community discussion, the image won't preview with the float styling directly in the Portable Text editor. However, you have a couple of options:
- Use the iframe preview pane plugin to show a live preview of your actual page alongside the editor
- Create a custom preview component for your image blocks that renders them with the appropriate styling in the editor itself (see Customizing the Editor)
Your clients coming from WordPress will find this familiar in the Studio interface (they can insert images inline between paragraphs), but you get much more flexibility in how that content gets rendered across web, mobile, email, or any other platform. This is the power of structured content - write once, render appropriately everywhere.
Show original thread8 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.