Skip to main content

What is Portable Text?

Portable Text is Sanity’s rich text format—a structured, JSON-based way to represent content that’s more powerful and flexible than HTML. Unlike HTML (which mixes content and presentation), Portable Text separates what the content is from how it looks. This makes your content:
  • Platform-agnostic - Render on web, mobile, email, or anywhere
  • Structured - Query and filter content programmatically
  • Customizable - Style differently across platforms
  • Future-proof - Not tied to specific HTML/CSS

Portable Text Structure

Portable Text is an array of blocks and marks:
[
  {
    "_type": "block",
    "style": "h2",
    "children": [
      {
        "_type": "span",
        "text": "Welcome to Sanity",
        "marks": []
      }
    ]
  },
  {
    "_type": "block",
    "style": "normal",
    "children": [
      {
        "_type": "span",
        "text": "This is a ",
        "marks": []
      },
      {
        "_type": "span",
        "text": "paragraph",
        "marks": ["strong"]
      },
      {
        "_type": "span",
        "text": " with formatting.",
        "marks": []
      }
    ]
  }
]
This represents:
<h2>Welcome to Sanity</h2>
<p>This is a <strong>paragraph</strong> with formatting.</p>

Key Concepts

Blocks

Blocks are the main content units:
  • Paragraphs - style: "normal"
  • Headings - style: "h1" through style: "h6"
  • Lists - listItem: "bullet" or listItem: "number"
  • Custom blocks - Images, code, embeds, etc.

Marks

Marks are inline annotations:
  • strong - Bold text
  • em - Italic text
  • underline - Underlined text
  • code - Inline code
  • link - Hyperlinks with href

Spans

Spans are text segments within blocks, each with its own marks.

How MigrateKit Converts HTML

When you migrate from Webflow, MigrateKit transforms HTML to Portable Text:
  • HTML Input
  • Portable Text Output
<h2>My Blog Post</h2>
<p>This is <strong>important</strong> text with a <a href="/link">link</a>.</p>
<ul>
  <li>First item</li>
  <li>Second item</li>
</ul>
Learn more: HTML Conversion

Benefits for Migration

Preservation of Structure

HTML tags become semantic blocks:
HTMLPortable TextBenefit
<h2>style: "h2"Heading semantics preserved
<strong>marks: ["strong"]Emphasis meaning, not just bold
<ul><li>listItem: "bullet"List structure, not just bullets

Platform Flexibility

Render Portable Text differently on different platforms:
// Web - styled as H1
<h1 className="text-4xl">{heading}</h1>

// Mobile - styled as H2 for smaller screens
<h2 className="text-2xl">{heading}</h2>

// Email - inline styles
<h2 style="font-size: 24px">{heading}</h2>
All from the same Portable Text source!

Querying and Filtering

Find content programmatically:
// Find all documents with links to /pricing
*[_type == "post" && pt::text(body) match "*pricing*"]
You can’t do this easily with HTML.

Editing Portable Text

In Sanity Studio, Portable Text appears as a rich text editor: Editors see familiar formatting options:
  • Bold, italic, underline buttons
  • Heading dropdown
  • List buttons
  • Link insertion
  • Undo/redo
But behind the scenes, it’s all stored as structured Portable Text.

Custom Block Types

Portable Text isn’t limited to text—you can embed custom content:
[
  {
    "_type": "block",
    "children": [{"_type": "span", "text": "Check out this image:"}]
  },
  {
    "_type": "image",
    "asset": {"_ref": "image-abc123-jpg"}
  },
  {
    "_type": "callout",
    "tone": "warning",
    "text": "Important notice!"
  }
]
This allows rich, interactive content while keeping structure.

Why This Matters for Webflow Migrations

From HTML Chaos to Structured Content

Webflow stores rich text as HTML—a mix of content, structure, and styling. Portable Text separates these concerns:
AspectHTML (Webflow)Portable Text (Sanity)
ContentMixed with tagsPure text in children
StructureImplicit in tagsExplicit in _type and style
FormattingCSS classes/inline stylesSemantic marks
PortabilityWeb-specificPlatform-agnostic

Better Content Management

  • Cleaner - No HTML tag soup
  • Safer - No script injection risks
  • Flexible - Render anywhere, any way
  • Searchable - Query content semantically

Common Questions

Yes! Sanity supports HTML in Portable Text through custom serializers. But you lose some benefits:
  • Can’t query HTML content semantically
  • Platform-specific rendering is harder
  • Less structured
MigrateKit converts HTML to Portable Text to give you maximum flexibility.
MigrateKit handles most common HTML tags, but complex structures may need manual cleanup:
  • Custom Webflow elements → Code blocks (review in Studio)
  • Nested formatting → Simplified to Portable Text rules
  • Unsupported tags → Wrapped for safety
See HTML Conversion for details.
In Sanity Studio, you edit using the rich text editor (WYSIWYG). To see the raw Portable Text JSON, use Sanity’s Vision plugin.You typically don’t need to edit Portable Text as JSON—the editor handles it.
Portable Text is an open specification created by Sanity. While Sanity uses it extensively, you can use Portable Text in any system. It’s just JSON!

Learn More