The Richtext field
Storyblok comes with a powerful Richtext editor that saves your content in a structured JSON format. You can customize the toolbar for each field individually and even let the user insert Storyblok blocks. If you have written your content in Markdown you have the possibility to import it using the toolbar button "Paste from Markdown".

Rich text editor of Storyblok
Configuration options
Toolbar items
This option lets you define the toolbar items that are available for the user.
Allows only specific components to be inserted
This option lets you define the components that can be inserted by the "Add block" toolbar button.
How to render Richtext data to HTML?
To render the content of the Richtext field our SDKs come with a render function.
Javascript SDK
Following an example how to render a Richtext field with the Storyblok JS client.
const StoryblokClient = require('storyblok-js-client')
let Storyblok = new StoryblokClient({
accessToken: 'YOUR_TOKEN'
})
Storyblok.richTextResolver.render(data.richtext_field)
// Returns a html string
// Example in Plain Javascript
Storyblok.setComponentResolver((component, blok) => {
switch(component) {
case 'my_button':
return `<button>${blok.button_text}</button>`
break;
case 'contact_form':
return `<a href="mailto:${blok.mail}">Mail me at: ${blok.mail}</a>`
break;
}
})
/*
Example in Vue.js with the
usage of v-runtime-template to
render dynamic components
*/
Storyblok.setComponentResolver((component, blok) => {
return `<component :blok='${JSON.stringify(blok)}'
is="${component}"></component>`
})
Ruby SDK
Following is an example of rendering a Richtext field with the Storyblok Ruby client.
client = Storyblok::Client.new(token: 'YOUR_TOKEN')
client.render(data.richtext_field)
# Returns a html string
If you want to render inline components you need to define a component resolver function like the following:
# Option 1: Define the resolver when initializing
client = Storyblok::Client.new(
component_resolver: ->(component, data) => {
case component
when 'button'
"<button>#{data['text']}</button>"
when 'your_custom_component'
"<div class="welcome">#{data['welcome_text']}</div>"
end
}
)
# Option 2: Define the resolver afterwards
client.set_component_resolver(->(component, data) {
"#{component}"
})
Python SDK
This example shows how to use the pip package storyblok-richtext
.
First, install it via the following command:
pip install storyblok-richtext
Then render a richtext field like this:
from storyblok_richtext import Richtext
resolver = Richtext()
data = # get the data from the storyblok api
resolver.render(data.story.your_field)
PHP SDK
This example shows how to use the composer package storyblok/richtext-resolver
.
First, install it via the following command:
composer require storyblok/richtext-resolver dev-master
Then render a richtext field like this:
<?php
require __DIR__ . '/vendor/autoload.php';
use Storyblok\RichtextRender\Resolver;
$resolver = new Resolver();
$json = json_decode(file_get_contents('https://api.storyblok.com/v1/cdn/stories/tp/gatsby-multilanguage-website-tutorial?version=published&token=AX6tIYuiZIoGnDAr5wRZFwtt'), true);
$data = $json['story']['content']['body'][0]['richtext'];
echo $resolver->render($data);
Vue.js
This example shows how a Richtext component could look like in Vue.js
<template>
<div>
<div v-html="richtext"></div>
</div>
</template>
<script>
import Storyblok from 'storyblok-js-client'
const Api = new Storyblok()
export default {
props: ['text'],
computed: {
richtext() {
return this.text ? Api.richTextResolver.render(this.text) : ''
}
}
}
</script>
In the case of Nuxt/Vue, we recommend using this great community package made by Marvin Rudolph one of our ambassadors: Documentation & Github repository.
Nuxt.js or Gridsome
This example shows how a Richtext component could look like in Nuxt.js or Gridsome.
<template>
<div>
<div v-html="richtext"></div>
</div>
</template>
<script>
export default {
props: ['text'],
computed: {
richtext() {
return this.text ? this.$storyapi.richTextResolver.render(this.text) : ''
}
}
}
</script>
In the case of Nuxt/Vue, we recommend using this great community package made by Marvin Rudolph one of our ambassadors: Documentation & Github repository.
Components inside the Richtext field
What makes the Richtext field really powerful is the possibility to insert components. This lets you extend the functionality of the editor to render custom elements.
To render these components be sure to define a component resolver like shown in the section "How to render Richtext data to HTML" above.
Usually you don't want that your users insert all types of components in the Richtext field so you can restrict the type with the option "Allow only specific components to be inserted".

Rich text editor with inline components inside
Migration from the Markdown field
Currently you have two options to migrate a Markdown field to Richtext field.
Create a new field in the schema of your component, copy the content of the Markdown field and insert it with the "Paste from Markdown" button to the new field.
Change the fieldtype of the Markdown field to a Richtext field. This will not immediately change Markdown to the Richtext format so you will need to include a check for the type in your code:
if (typeof data.markdown_field === 'string') {
return marked(data.markdown_field)
} else {
return Storyblok.richTextResolver.render(data.markdown_field)
}
Tech stack of RT Editor
Our rich text editor is built using TipTap rich text editor. Check out their documentation if you want to build your own version of the Rich Text editor field.