Examples of complex block contents for WordPress to Sanity migration
Absolutely! Sanity's Block Content and Custom Blocks capabilities are perfect for replacing WordPress galleries and advanced content blocks. Unlike basic rich text editors, Sanity's Portable Text lets you embed custom content types directly within articles—including image galleries, carousels, and any other complex components your authors need.
How Custom Blocks Work
In Sanity, you define custom block types in your schema and add them to your Portable Text arrays. This gives authors the ability to insert rich media and interactive components right alongside their text content. Here's an example of creating an image gallery block:
// schemas/imageGallery.ts
import {defineType, defineField} from 'sanity'
export const imageGallery = defineType({
name: 'imageGallery',
type: 'object',
title: 'Image Gallery',
fields: [
defineField({
name: 'images',
type: 'array',
title: 'Gallery Images',
of: [{
type: 'image',
fields: [
{
name: 'caption',
type: 'string',
title: 'Caption'
},
{
name: 'alt',
type: 'string',
title: 'Alt Text'
}
]
}]
}),
defineField({
name: 'layout',
type: 'string',
title: 'Gallery Layout',
options: {
list: [
{title: 'Grid', value: 'grid'},
{title: 'Carousel', value: 'carousel'},
{title: 'Masonry', value: 'masonry'}
]
}
})
],
preview: {
select: {
images: 'images',
layout: 'layout'
},
prepare({images, layout}) {
return {
title: `${layout || 'Gallery'} (${images?.length || 0} images)`,
media: images?.[0]
}
}
}
})Then add it to your article body field:
// schemas/article.ts
defineField({
name: 'body',
type: 'array',
title: 'Article Content',
of: [
{type: 'block'}, // Standard rich text
{type: 'image'}, // Single images
{type: 'imageGallery'}, // Your gallery block
{type: 'videoEmbed'}, // Video embeds
// Add any other custom blocks
]
})Rendering on the Frontend
When rendering your content, you provide React components for each custom block type using @portabletext/react:
import {PortableText} from '@portabletext/react'
const ImageGalleryComponent = ({value}) => {
const {images, layout} = value
if (layout === 'carousel') {
return <Carousel images={images} />
}
return (
<div className="image-grid">
{images.map((img, i) => (
<figure key={i}>
<img src={img.url} alt={img.alt} />
{img.caption && <figcaption>{img.caption}</figcaption>}
</figure>
))}
</div>
)
}
const ptComponents = {
types: {
imageGallery: ImageGalleryComponent,
// Add other custom block components
}
}
// In your page component
<PortableText components={ptComponents} value={article.body} />More Complex Examples
You can create blocks for virtually any content type:
Carousel with captions:
{
name: 'carousel',
type: 'object',
fields: [
{
name: 'slides',
type: 'array',
of: [{
type: 'object',
fields: [
{name: 'image', type: 'image'},
{name: 'caption', type: 'text'},
{name: 'link', type: 'url'}
]
}]
},
{
name: 'autoplay',
type: 'boolean',
title: 'Auto-advance slides'
}
]
}Split image/text layout:
{
name: 'imageTextSplit',
type: 'object',
fields: [
{name: 'image', type: 'image'},
{name: 'text', type: 'text'},
{
name: 'imagePosition',
type: 'string',
options: {
list: ['left', 'right']
}
}
]
}Why This Works Better Than WordPress
Structured data: Unlike WordPress HTML blocks, Sanity stores your galleries as structured JSON. This means you can query, filter, and repurpose your content across different platforms (web, mobile apps, etc.)
Type safety: Your content structure is validated and type-safe, preventing content errors
Platform agnostic: The same content can render differently on web vs mobile without storing separate versions
Future-proof: If you redesign your site or change how galleries display, you just update the rendering component—your content stays the same
Modular and reusable: Custom blocks work like Lego bricks that can be assembled into unique layouts while maintaining consistency
Your authors will get an intuitive editing experience where they can insert galleries, carousels, and other rich content directly into articles—just like WordPress blocks, but with much more flexibility and portability. The Portable Text editor is highly configurable, so you can customize it to match your team's specific workflow.
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.