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".

Richtext

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

If you want to render inline components you need to define a component resolver function like following:

// 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 an example how to render 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 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 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 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);

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>

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>

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".

Migration from the Markdown field

Currently you have two options to migrate a Markdown field to Richtext field.

  1. 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.

  2. 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)
}